此代码的行为是否定义明确?
#include <stdio.h>
#include <pthread.h>
pthread_t mt;
void *start(void *x)
{
void *y;
pthread_join(mt, &y);
printf("joined main thread\n");
return 0;
}
int main()
{
pthread_t t;
mt = pthread_self();
pthread_create(&t, 0, start, 0);
pthread_exit(0);
}
答案 0 :(得分:8)
是的,这是可能的。实际上,这种可能性是pthread_detach()
存在的主要原因之一。来自pthread_detach()
的POSIX文档(请参阅man pthread_detach
):
It has been suggested that a "detach" function is not necessary; the
detachstate thread creation attribute is sufficient, since a thread
need never be dynamically detached. However, need arises in at least
two cases:
1. In a cancellation handler for a pthread_join() it is nearly essen-
tial to have a pthread_detach() function in order to detach the
thread on which pthread_join() was waiting. Without it, it would
be necessary to have the handler do another pthread_join() to
attempt to detach the thread, which would both delay the cancella-
tion processing for an unbounded period and introduce a new call
to pthread_join(), which might itself need a cancellation handler.
A dynamic detach is nearly essential in this case.
2. In order to detach the "initial thread" (as may be desirable in
processes that set up server threads).
所以根据标准,你提出的建议很好。
修改:进一步确认POSIX description of exec()
州:
新流程中的初始线程 图像应该是可连接的,就像创建一样 将detachstate属性设置为 PTHREAD_CREATE_JOINABLE。
答案 1 :(得分:0)
我无法想象为什么你会在现实世界的应用程序中这样做(有人请你注意一个例子,如果你能想到一个),但我不相信它甚至是可能的。我查看的有关pthread的所有搜索总是从主线程调用连接,而不是辅助线程。
连接还要求使用PTHREAD_CREATE_JOINABLE标志创建您尝试加入的线程。我无法找到任何文档说明主线程是否是这样创建的。
Codeguru在其上有一个类似的问题here,可能会或可能不会帮助澄清它。
如果要完成的是子线程在主线程退出后继续,则应该创建子线程分离,或者使用fork
/ vfork
代替,具体取决于您的平台重新开始。
答案 2 :(得分:0)
您的方法看起来对我来说正式有效,特别是因为您在pthread_exit
结束时正在执行main
。
另一方面,我没有在POSIX中找到任何指示main
的初始线程是否可以加入。 psmears回答的基本原理只是要求main
应该是可分离的,从而可以将其创建为可连接的。
恶意的其他东西也可能从main调用的子程序中调用pthread_detach
。因此,您应该明确检查pthread_join
的返回值,以检查这种情况。
同样在您的示例代码中,您在创建start
和终止main
之间进行了竞赛:
main
可能会在start
到达pthread_join
对mt
变量的访问进行静音应该能够实现。