【问题标题】:What if a being-waited thread detaches itself?如果一个正在等待的线程分离了自己怎么办?
【发布时间】:2014-12-03 03:03:48
【问题描述】:
#include <pthread.h>

void thread_routine(void*)
{
    sleep(5);
    pthread_detach(pthread_self());
    sleep(5);
}

int main()
{
    pthread_t t;
    pthread_create(&t, 0, thread_routine, 0);
    pthread_join(t);
}

pthread_join(t); 会在pthread_detach(pthread_self()); 成功后立即返回吗?

【问题讨论】:

  • 我的猜测,就像在调用pthread_join:UB之前线程被分离一样。

标签: c linux multithreading pthreads posix


【解决方案1】:

这种行为是未定义的,因此显然要不惜一切代价避免。

(据我所知,这种行为是隐含未定义的。explicitly undefined behavior in the spec 有几个类似的实例,但没有提到这个确切的场景。)

为了好奇,在我附近的一个 NPTL Linux 系统上,pthread_detach()pthread_join() 都返回 0,而且,后者阻塞并成功获取线程返回的值。相比之下,在我附近的 OS X 系统上,pthread_detach() 成功,pthread_join() 立即因 ESRCH 而失败。

【讨论】:

    【解决方案2】:

    您的代码有问题。当您调用pthread_join 时,线程可能已经终止。由于已分离,pthread_t 不再有效。因此您的代码可能会将无效的pthread_t 传递给pthread_join,这可能会导致不可预知的行为。

    为了避免这些问题,应该有一件特定的事情来控制线程的生命周期。那可能是线程本身,如果它是分离的,在这种情况下,没有线程应该尝试加入它。它也可以是加入它的线程,在这种情况下线程不应该被分离。

    【讨论】:

    • 这都是真实而伟大的指导,但有点离题。 OP 的问题是,如果作为连接目标的线程在连接期间分离自身会发生什么?确实sleep() 是傻瓜同步的黄金,而且OP 的thread_routine 可以main 线程开始调用join 之前终止其10 秒的生命。然而,在实践中,该帖子是@xmllmx 所要求的一个很好的设计,您不会直接回答。
    • 我想说,在这种情况下,归结为可以在 pthread_t 上同时调用哪些函数。
    • @pilcrow 无论您如何创建比赛,答案都是一样的。该行为是不可预测的,因为您无法保证 pthread_t 仍然有效。
    • 我不知道我们说的是不是同一件事。 :) 让我换个说法:问题是当一个有效/可行的pthread_t 是一个连接的目标,然后当连接正在进行时也是一个detach 的目标时会发生什么。 pthread_t 在呼叫时对每个呼叫者都有效。
    • @pilcrow 是的,我的回答是总会有竞争条件,所以它总是不可预测的。尝试在没有竞争条件的情况下编写这样的代码你不能这样做。 (想想看,你怎么知道加入正在进行而不是等待开始?)
    猜你喜欢
    • 2017-06-03
    • 1970-01-01
    • 1970-01-01
    • 2016-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-13
    相关资源
    最近更新 更多