在主线程上调用pthread_join是否有效?

时间:2010-11-19 18:31:52

标签: c pthreads posix

此代码的行为是否定义明确?

#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);
}

3 个答案:

答案 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变量的访问进行静音应该能够实现。