[英]How does a thread in NPTL exit?
从实现的角度来看,我很好奇单个 NPTL 线程是如何退出的。
我对glibc-2.30的实现的理解是:
_exit()
系统调用杀死线程组中的所有线程。pthread_create()
接收的用户 function 实际上被包装到另一个 function start_thread()
中,它在运行用户 ZC1C425268E68385D1AB5074C17A94 之前做了一些准备工作。问题是:
在包装器 function start_thread()
的末尾,有以下注释和代码:
/* We cannot call '_exit' here. '_exit' will terminate the process. The 'exit' implementation in the kernel will signal when the process is really dead since 'clone' got passed the CLONE_CHILD_CLEARTID flag. The 'tid' field in the TCB will be set to zero. The exit code is zero since in case all threads exit by calling 'pthread_exit' the exit status must be 0 (zero). */ __exit_thread ();
但__exit_thread()
似乎无论如何都在做系统调用_exit()
:
static inline void __attribute__ ((noreturn, always_inline, unused)) __exit_thread (void) { /* some comments here */ while (1) { INTERNAL_SYSCALL_DECL (err); INTERNAL_SYSCALL (exit, err, 1, 0); } }
所以我在这里很困惑,因为它不应该真正执行系统调用_exit()
因为它会终止所有线程。
pthread_exit()
应该终止单个线程,因此它应该执行类似于包装器start_thread()
最后所做的事情,但是它调用__do_cancel()
,并且TBH 我迷失在追查那个 function 中。 它似乎与上面的__exit_thread()
,也没有调用_exit()
。我在这里很困惑,因为它不应该真正做系统调用 _exit()
这里的混淆源于将exit
系统调用与_exit
libc 例程混合在一起(Linux 上没有_exit
系统调用)。
前者终止当前的 Linux 线程(如预期的那样)。
后者(令人困惑)不执行exit
系统调用。 相反,它执行exit_group
系统调用,终止所有线程。
thread_exit() 应该终止单个线程
它确实,间接地。 它展开当前堆栈(类似于siglongjmp
),将控制转移到设置cleanup_jmp_buf
的位置。 那是在start_thread
。
控制转移后, start_thread
清理资源,并调用__exit_thread
实际终止线程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.