Как функция потока может обращаться к переменным родительского потока - PullRequest
5 голосов
/ 17 октября 2010

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

void* PrintVar(void* arg){
   printf( "%d\n", a);
}

int main(int argc, char*argv[]) {
   int a;
   a = 10;
   pthread_t thr;
   pthread_create( &thr, NULL, PrintVar, NULL );

}

Если поток разделяет адресное пространство, то функция PrintVar должна была бы печатать значение variable a, верно?

Я прочитал эту информацию на http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html

Потоки в одном и том же процессе: Инструкции по процессу Большинство данных открытые файлы (дескрипторы) сигналы и обработчики сигналов текущий рабочий каталог Идентификатор пользователя и группы

Если это так, то почему int a не относится к общей переменной?

Я хотел бы увидеть пример кода, где дескрипторы файлов являются общими

Ответы [ 2 ]

7 голосов
/ 17 октября 2010

Дочерний поток может обращаться к переменной в стеке родительского потока, ему просто нужно знать адрес переменной.Например, вы можете сделать это следующим образом:

void* PrintVar(void* arg){
   int * a = (int *) arg;
   printf( "%d\n", *a);
}

int main(int argc, char*argv[]) {
   int a;
   a = 10;
   pthread_t thr;
   pthread_create( &thr, NULL, PrintVar, &a );
}

Обратите внимание, что такого рода вещи могут быть хитрыми, так как вы должны (так или иначе) гарантировать, что (а) не будет уничтожен, покадочерний поток все еще обращается к нему.(В этом случае вы, вероятно, захотите вызвать pthread_join () в конце main (), чтобы основной поток блокировался там и не возвращался из main () до тех пор, пока не завершится дочерний поток)

4 голосов
/ 17 октября 2010

вы не могли бы сделать это, даже если бы это не был поток, потому что a выходит за рамки.

поместите a в глобальную область, например, так:

int a;
void* PrintVar(void* arg){
   printf( "%d\n", a);
}

int main(int argc, char*argv[]) {
   a = 10;
   pthread_t thr;
   pthread_create( &thr, NULL, PrintVar, NULL );

}

Thisна самом деле это не вопрос потоков.рассмотрим следующий код:

void PrintVar(){
   printf( "%d\n", a);
}

int main(int argc, char*argv[]) {
   int a;
   a = 10;
   PrintVar();
}

Это, очевидно, не сработает, потому что имя переменной a, объявленное в main, не видно в PrintVar, поскольку оно находится в локальной области видимости другого блока.,Это проблема времени компиляции, компилятор просто не знает, что вы подразумеваете под a, когда упоминаете об этом в PrintVar.

Но есть и другая проблема с многопоточностью.когда основной поток процесса завершается, все другие потоки завершаются (в частности, когда любой поток вызывает _exit, тогда все потоки завершаются, а _start вызывает _exit после возврата main).но ваш основной возвращается сразу после вызова другого потока.Чтобы предотвратить это, вы должны вызвать pthread_join, который будет ждать завершения потока перед возвратом.это будет выглядеть так

int a;
void* PrintVar(void* arg){
   printf( "%d\n", a);
}

int main(int argc, char*argv[]) {
   void *dummy;
   a = 10;

   pthread_t thr;
   pthread_create( &thr, NULL, PrintVar, NULL );
   pthread_join( thr, &dummy);
}
...