C — Повторно использовать struct в качестве аргумента для нескольких PThreads

#c #struct #pthreads

#c #struct #pthreads

Вопрос:

У меня есть цикл while, и для каждой итерации цикла я создаю и заполняю структуру и создаю поток, передавая эту структуру в качестве аргумента потоковой функции.

Это вызывает некоторые проблемы — мой цикл while обновляет данные в структуре, прежде чем моя потоковая функция получит возможность создавать локальные копии данных структуры.

Кто-нибудь знает хороший способ повторного использования структуры для нескольких потоков? Я думал об использовании какого-нибудь флага, чтобы заставить основной поток ждать, пока потоковая функция не получит свою собственную копию, но, похоже, это привело бы к ненужному ожиданию.

Вот пример того, чего я пытаюсь достичь:

 struct parameters {
    int val1;
    int val2;
    int val3;
};

int main() {
    ...
    while (readLine(file)) {
        ...
        struct parameters *myParameters = malloc(sizeof(struct parameters));
        myParameters.val1 = line.val1;
        myParameters.val2 = line.val2;
        myParameters.val3 = line.val3;

        pthread_t myThread;
        pthread_create(amp;myThread, NULL, amp;print, myParameters);
        free(myParameters);
    }
}

void *print(void *param) {
    struct parameters *localParameters = param;
    int threadVal1 = localParameters->val1;
    int threadVal2 = localParameters->val2;
    int threadVal3 = localParameters->val3;
}
  

Комментарии:

1. «Кто-нибудь знает хороший способ повторного использования структуры для нескольких потоков?» Уммм… Не надо. Память дешева, особенно для такого рода использования. В противном случае вам пришлось бы использовать что-то вроде семафора, монитора или переменной условия для дочернего потока, чтобы сообщить родительскому потоку, что это сделано с информацией. Это было бы излишне болезненно.

2. Если вы не используете какой-либо механизм синхронизации потоков, я не думаю, что вы сможете повторно использовать переменную. Но уверены ли вы в повторном использовании переменной в коде yopur? Вы объявляете «myParameters» внутри цикла while.

3. @MayurK Большинство реализаций будут повторно использовать одни и те же расположения стека для этой переменной, даже если технически это новая переменная на каждой итерации. Но это подчеркивает еще худшую проблему с этим кодом в целом (хотя и не конкретно в этом случае) — передача потоку адреса во фрейме стека, который может прекратить существование в течение срока службы потока, является особенно плохой идеей.

4. @twalberg Да. Я думаю, что всегда лучше указывать параметр потока malloc и передавать. Никакой путаницы не будет.

5. @twalberg Я изменил struct parameters myParameters на struct parameters *myParameters = malloc(sizeof(struct parameters)); , но по-прежнему кажется, что структура каким-то образом перезаписывается, прежде чем мой поток сможет получить копию. Где я должен освобождать эту память?