在POSIX线程的大多数实现中,在新创建的线程处于能够运行应用程序代码的一致状态之前,需要进行一些初始化。这可能涉及解锁线程结构中的锁,在使用一个的实现中初始化“线程寄存器”,初始化线程本地数据(编译器级别的TLS或POSIX线程特定的数据)等。我找不到清楚的保证在线程可以接收任何信号之前完成所有这些初始化;我能找到的最接近的是2.4.3:
下表定义了一组异步信号安全的函数。因此,应用程序可以无限制地调用信号捕获功能:
...
据推测,其中一些函数(至少fork
必须检查由pthread_atfork
函数建立的全局状态)取决于线程处于一致的初始化状态。
困扰我的一件事是我已经阅读了很多glibc / nptl源代码,并且无法找到任何显式同步来阻止信号在完全初始化之前被新创建的线程处理。我希望调用pthread_create
的线程在调用clone
之前阻塞所有信号,并且在初始化完成后让新线程解除阻塞,但是我找不到任何代码也没有在strace
输出中看到它。
答案 0 :(得分:1)
(我不认为这是一个真正的答案,但是评论很重要)
这是一个非常有趣的问题。我查看了pthread_create
的glibc代码,看看它是如何表现的,除非我完全遗漏了一些似乎没有任何特殊行为来阻止它(例如在{{1}之前阻塞所有信号并且在一些设置之后将它们解锁到子节点中{在记录线程创建时间之后并且C ++捕获所有异常处理程序已经设置,即使在C代码中也会发生}。)
我期待找到一条评论,提到这种情况的可能性,甚至可能提到POSIX所说的事情(或者提到它没有说明要做什么)。
也许你应该始终在代码中包装clone
来阻止和恢复信号,并使用unblock调用启动所有线程函数。
这很可能是pthreads中的过度站点(或glibc或我对代码的理解)。
答案 1 :(得分:0)
POSIX pthread_create
specification要求我理解:
新线程的信号状态应初始化如下:
- 信号掩码应从创建线程继承。
- 新线程待处理的信号集应为空。
但我没有足够的经验说这些事情在各种实施中都是这样的。
答案 2 :(得分:-1)
pthread_create是一个阻止调用。它没有(新)线程在调用之前将信号发送到,并且是一个线程,用于在调用之后将信号发送到,因此线程的ID通过电话回复。
因此,我得出结论,该线程必须在那时有效并初始化......