主线程退出后线程访问共享变量
Posted
技术标签:
【中文标题】主线程退出后线程访问共享变量【英文标题】:thread access shared variables after main thread exit 【发布时间】:2015-06-07 23:47:59 【问题描述】:如果分离线程在调用线程退出后访问共享变量(例如全局变量)并破坏共享变量,在多线程 C++ 程序中会发生什么?
class A
public:
A() printf("Constructing A\n");
~A() printf("Destructing A\n");
void printSomething() printf("A is printing\n");
A a;
void thread_func()
printf("begin thread.\n");
sleep(3); // make sure main thread exit first
a.printSomething();
printf("ending thread");
int main(int argc, char** argv)
std::thread t(thread_func);
t.detach();
return 0;
程序产生:
bash$ ./a.out
Constructing A
Destructing A
bash$
似乎主线程创建了全局变量 a 并在退出时将其销毁。那么如果分离的子线程尝试访问这个全局变量,3秒后会发生什么?
另一个困惑是,为什么主线程退出时会清除所有资源?好像全局变量的生命周期只依赖于主线程?
【问题讨论】:
当主线程退出时,它也会破坏 t。如果你想让某些东西比 main 更长寿,请使用 fork。 线程函数中的printf()
语句在哪里?
printf() 语句并不是每次都在shell中输出。有时它会打印出“开始线程”。我认为这取决于两个线程的调度顺序。
【参考方案1】:
当main()
返回或任何线程调用exit()
或_exit()
时,进程退出。
但是,main()
可以调用 pthread_exit()
- 这将不会终止进程。根据 Linux pthread_exit()
man page:
当一个线程终止时,进程共享的资源(例如,互斥锁、 条件变量、信号量和文件描述符)不是 释放,并且使用 atexit(3) 注册的函数不会被调用。
进程中的最后一个线程终止后,进程终止 就像调用退出状态为零的 exit(3) 一样;因此, 进程共享资源被释放,函数注册使用 atexit(3) 被调用。
【讨论】:
【参考方案2】:线程本身没有自己的内存,但与它们的父进程共享内存。他们与父母联系在一起;因此,每当父母死亡时,它的子线程也会被杀死。
【讨论】:
即使child脱离了,在主线程退出时也会被kill掉? 所以分离一个线程并不会从它的父级移除它的依赖。当你分离一个线程时,它的父级不再需要杀死它来清理资源。分离的线程一旦退出,就会自动清理它们的内存,而不是要求父级pthread_join
它们。根据定义,线程不能作为它们自己的实体存在。它们必须是流程的一部分。以上是关于主线程退出后线程访问共享变量的主要内容,如果未能解决你的问题,请参考以下文章