C NPTL中的线程如何退出?
我很好奇,从实现的角度来看,单个NPTL线程是如何存在的 我对glibc-2.30实施的理解是:C NPTL中的线程如何退出?,c,linux-kernel,pthreads,system-calls,glibc,C,Linux Kernel,Pthreads,System Calls,Glibc,我很好奇,从实现的角度来看,单个NPTL线程是如何存在的 我对glibc-2.30实施的理解是: NPTL线程构建在Linux上的轻量级进程之上,附加信息存储在用户堆栈上的pthread对象中,以跟踪NPTL特定的信息,如连接/分离状态和返回对象的指针 当一个NPTL线程完成时,它将永远消失,只有用户堆栈(因此)pthread对象将被收集(由其他线程连接),除非它是分离的,在这种情况下,空间将被直接释放 \u exit()syscall杀死线程组中的所有线程 接收的用户函数实际上被包装到另一个函
\u exit()
syscall杀死线程组中的所有线程/* 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 ();
但无论如何,似乎都在执行syscall\u 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);
}
}
所以我在这里感到困惑,因为它不应该真正执行syscall\u exit()
,因为它将终止所有线程start\u thread()
最后所做的事情,但是它调用了,我在跟踪该函数时迷失了方向。它似乎与上面的\uuu exit\u thread()
无关,也不调用\u exit()
exit
系统调用与\u exit
libc例程混合(Linux上没有\u exit
系统调用)
前者终止当前Linux线程(如预期的那样)
后者(令人困惑地)不执行exit
系统调用。相反,它执行exit_group
系统调用,终止所有线程
线程_exit()应终止单个线程
这是间接的。它展开当前堆栈(类似于siglongjmp
),执行控制转移到设置cleanup_jmp_buf
的点。那是在start\u-thread
中
在控制转移之后,
start\u-thread
清理资源,并调用\u-exit\u-thread
实际终止线程。这就解释了一切,谢谢!我重新访问了手册页man2\u exit
,注释部分说“在glibc版本2.3之前的版本中,\u exit()
包装函数调用了同名的内核系统调用。自glibc2.3以来,包装器函数调用exit_group
(2),以终止进程中的所有线程。(原始的\u exit()
系统调用仅终止调用线程。)。这是一个过时的描述,还是在glibc 2.3之前有一个名为\u exit
的系统调用?在man
第2节中有一个\u exit
页面这一事实似乎有点奇怪。@QnA我同意:我认为\u exit
应该移到第3节,因为它描述了libc
函数,而不是系统调用。请随意提交一个bug。