从实现的角度来看,我很好奇单个NPTL线程是如何存在的。
我对glibc-2.的执行情况的理解是:
_exit() syscall杀死了线程组中的所有线程。pthread_create()接收的用户函数实际上被包装到另一个函数start_thread()中,它在运行用户函数之前做了一些准备,并在运行之后进行了一些清理。问题如下:
start_thread()的末尾,有以下注释和代码:/*我们不能在这里叫'_exit‘。“_exit”将终止该进程。内核中的“exit”实现将在进程真正死掉时发出信号,因为“克隆”通过了CLONE_CHILD_CLEARTID标志。TCB中的“tid”字段将设置为零。退出代码为零,因为如果所有线程通过调用'pthread_exit‘退出,退出状态必须为0(零)。*/ __exit_thread ();
但无论如何,__exit_thread()似乎都在做syscall _exit():
静态内联__attribute__ (( inline,always_inline,未使用)) __exit_thread ( /* ){在这里注释*/ /* (1) { INTERNAL_SYSCALL_DECL (err);INTERNAL_SYSCALL (exit,err,1,0);}
所以我在这里感到困惑,因为它不应该真的执行syscall _exit(),因为它将终止所有的_exit()应该终止一个线程,所以它应该做一些类似于包装器start_thread()最终所做的事情,但是它称为__do_cancel(),而我在跟踪这个函数时迷失了方向。它似乎与上述的_exit().无关,也不称之为__exit_thread()。
发布于 2020-05-27 05:21:08
我在这里很困惑,因为它不应该真的做syscall _exit()
这里的混乱源于将exit系统调用与_exit libc例程(在Linux上没有_exit系统调用)混合在一起。
前者终止当前Linux线程(如预期的那样)。
后者(令人困惑)不执行exit系统调用。相反,它执行exit_group系统调用,它终止所有线程。
thread_exit()应该终止单个线程
是间接的。它解压当前堆栈(类似于siglongjmp),执行控制转移到设置cleanup_jmp_buf的位置。那是在start_thread。
在控件传输之后,start_thread清理资源,并调用__exit_thread来实际终止线程。
https://stackoverflow.com/questions/62029447
复制相似问题