Но когда я передаю адрес переменной стека в функцию потока, и программа просто ждет всегда.
Нет никакой внутренней проблемы с передачей адреса автоматической переменной в функцию потока.На самом деле, это довольно распространено.Однако - это проблема, связанная с тем, что функция потока разыменовывает указатель по истечении времени жизни указанной переменной, и может возникнуть проблема другого типа, если значение указанной переменной равноизменен другим потоком, таким как родительский поток.
Ваша программа сталкивается с обоими типами проблем: она передает адрес локальной переменной i
, а затем изменяет значение этой переменной и затем время жизни этой переменной заканчивается, когда завершается цикл, что может легко произойти до того, как потоки попытаются использовать указатель.
Вы можете решить обе проблемы с соответствующей синхронизацией, чтобы функция потока читала переменную перед цикломпереходит к следующей итерации.Это было бы правильным решением для каждой соответствующей реализации.
Однако может быть проще преобразовать i
в указатель, передать результат и заставить функцию потока преобразовать егоназад.Оба преобразования демонстрируют поведение, определяемое реализацией, но на практике это прекрасно работает в большинстве систем.Документация вашей реализации должна содержать достаточно деталей, чтобы определить, поддерживает ли она этот подход, если вы хотите быть уверенным.
Например:
// Note that 'i' itself is converted to void *
int success = pthread_create(&p_id[i], NULL, thread_print, (void *) i);
// ...
void *thread_print(void *num) {
// Note that 'num' is converted directly (back) to an int, not dereferenced
int number = (int) num;
// ...
Обратите внимание, что sleep()
нерешить проблемы синхронизации.Лучше всего, это скрывает их, но в вашем конкретном случае это подчеркивает их.