#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));
, но по-прежнему кажется, что структура каким-то образом перезаписывается, прежде чем мой поток сможет получить копию. Где я должен освобождать эту память?