Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ pthread_加入我自己是否可以接受和安全?_C++_Thread Safety_Pthreads - Fatal编程技术网

C++ pthread_加入我自己是否可以接受和安全?

C++ pthread_加入我自己是否可以接受和安全?,c++,thread-safety,pthreads,C++,Thread Safety,Pthreads,我有一个类似这样的设置: 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 cle

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

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

我的问题是:这样做可以吗?如果可以,安全吗?(因此忽略连接失败,因为我马上就可以很好地结束线程了?)或者,这是应该避免的吗

   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\u join()
,否则会有失败的风险。

您当然可以从正在运行的线程本身调用
pthread\u join()
,并且当您发现调用本身会正确处理它,并给出错误代码。但是,也存在一些问题:

  • 这没有任何意义,因为连接不会连接任何内容。它只会告诉你你做错了什么
  • 在对线程本身调用
    pthread\u join()
    时,线程本身不会退出
  • 即使线程存在,也无法正确清理其状态。其他一些线程(即应用程序的主线程)应该调用
    pthread\u join()
    ,除非该线程被创建为“已分离”
  • 换句话说,这种方法就像程序中的bug一样可以接受

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

    如果要结束工作线程,请从线程例程返回或调用。然后确保启动线程的人通过调用
    pthread\u join()
    来清理问题


    如果您想强制线程停止,请考虑使用信号来发送线程,或者,可以实现某种消息传递,您可以使用它来“告诉”线程停止执行它正在做的任何事情。

    这正是我正在寻找的解释。非常感谢!这种方法经常导致“清理问题”。如果分离的线程引用了一些内存,甚至是静态对象,并且在分离的线程结束之前引用了主线程,则会发生各种损坏(coredump并不罕见)。最好正确地清理并加入。@Mekk:。。。或者通过调用
    pthread\u exit()
    ,离开
    main()
    (从线程的角度来看,它只是其他线程之外的另一个线程)。在这种情况下,谁来执行全局和静态对象的析构函数?还有更多C-ish代码中的ATEXIT?@Mekk:当流程结束时,这一切都完成了,这是它的最后一个线程。相信我:这个“流程结束”阶段比看起来要复杂得多,至少在你的应用程序有各种线程的情况下,它们都需要完成一些工作,并在完成这些工作时使用一些静态或全局资源。我已经分析了很多。”“结束阶段”崩溃。显式加入线程(在通知线程必须结束后)使其更易于管理。当然:如果线程是自给自足的,不使用共享资源,并且没有人关心它是在对等线程之前还是之后完成,它可以分离。