#include <pthread.h>
#include <unistd.h>
static void *tfunc(void *data)
{
return NULL;
}
int main(int argc, char **argv)
{
pthread_t t;
pthread_create(&t, NULL, tfunc, NULL);
sleep(1);
pthread_detach(t);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
参见MWE.它工作正常,但我不确定这是否是实际定义的行为.手册中pthread_detach没有提及在退出的线程上调用它.
是的我知道创建具有分离属性的线程,但我对这种情况特别好奇.pthread_join对这个案子有提及,我认为pthread_detach工作同样好,但我没有找到任何官方声明.
此代码完全合法,并且不会调用未定义的行为:
#include <pthread.h>
#include <unistd.h>
static void *tfunc(void *data)
{
return NULL;
}
int main(int argc, char **argv)
{
pthread_t t;
pthread_create(&t, NULL, tfunc, NULL);
sleep(1);
pthread_detach(t);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它没有明确说明,但POSIX文档的pthread_detach()措辞是这样的,它必须被定义并且正确调用pthread_detach()终止线程:
该
pthread_detach()函数应向实现指示当该线程终止时可以回收线程线程的存储.如果线程尚未终止,则pthread_detach()不应使其终止.如果thread参数指定的值
pthread_detach()未引用可连接线程,则行为未定义.
首先,请注意语句"如果线程尚未终止".这意味着,它必须是安全的调用pthread_detach()当线程已经终止.
其次,请注意"如果......不引用可连接线程,则行为未定义".在您发布的代码中,您创建的线程显然是可连接的 - 您没有使用分离属性创建它,因此您可以调用pthread_join()以检索其返回的值.所以这不是未定义的行为.
请记住,没有任何保证的方法可以确保线程A线程B在被调用pthread_join()或被pthread_detach()调用时仍在运行.所以要么从任何其他线程上的任何线程调用(一次!)都要安全.
另外,从POSIX文档的Rationale部分:
基本原理
该
pthread_join()或pthread_detach()函数最终应要求被创建,以便与线程关联的存储可再生每个线程.有人建议不需要"分离"功能; detachstate线程创建属性就足够了,因为线程永远不需要动态分离.但是,至少需要两种情况:
在取消处理程序中,为了分离正在等待的线程
pthread_join(),有一个pthread_detach()函数几乎是必不可少的pthread_join().没有它,有必要让处理程序执行另一个pthread_join()尝试分离线程,这将延迟无限期的取消处理并引入新的调用pthread_join(),这可能本身需要一个取消处理程序.在这种情况下,动态分离几乎是必不可少的.为了分离"初始线程"(在设置服务器线程的进程中可能需要).
同样,虽然没有明确说明,但请注意pthread_join()和之间的隐含等价pthread_detach().