我自己pthread_join是可以接受和安全的吗?

Is it acceptable and safe to pthread_join myself?

本文关键字:安全 pthread join 我自己      更新时间:2023-10-16

我有一个类似这样的设置:

void* work(void*) { while (true) {/*do work*/} return 0;}
class WorkDoer
{
private:
    pthread_t id;
public:
    WorkDoer() { pthread_create(&id, NULL, work, (void*)this); }
    void Shutdown() { pthread_join(id, NULL); /*other cleanup*/ }
}

在某些情况下,Shutdown()是从主线程调用的,而在其他一些情况下,我想从线程本身内部调用shutdown(之后从该线程返回)。

pthread_join()的文档说,如果调用线程与传递的线程相同,它将返回一个EDEADLK

我的问题是:这是一个可以做的事情,如果是这样,它是安全的吗?(因此忽略连接失败,因为无论如何我将很好地结束线程?)或者,这是应该避免的事情吗?

当然可以从正在运行的线程本身调用pthread_join(),并且正如您已经发现的那样,调用本身将正确地处理它,并给您一个错误代码。然而,有几个问题:

  1. 这没有任何意义,因为连接不会连接任何东西。它只会告诉你你做错了什么。
  2. 线程在调用pthread_join()时不会退出。
  3. 即使线程存在,它的状态也不会被正确清理。其他线程(即你的应用程序的主线程)应该调用pthread_join(),除非该线程被创建为"分离"。

因此,换句话说,这种方法与程序中的错误一样可以接受。

作为一种解决方案,我建议重新审视设计,并确保从正确的位置和正确的时间调用Shutdown()。毕竟,"关机"这个名字在这里没有多大意义,因为它并没有关闭任何东西。它所做的只是等待线程完成并在此之后清理其状态。

当你想结束工作线程时,要么从线程例程返回,要么调用pthread_exit()。然后确保启动线程的人通过调用pthread_join()来清理这些东西。

如果你想强制线程停止,考虑使用pthread_kill()来通知一个线程,或者,或者,实现某种消息传递,你可以使用它来"告诉"线程停止做它正在做的事情。

   The pthread_join() function may fail if:
   EDEADLK
          A deadlock was detected or the value  of  thread  specifies  the
          calling thread.

为什么不让线程调用pthread_detach(pthread_self());然后退出呢?没有必要再调用pthread_join(),并冒着失败的风险。