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:当流程结束时,这一切都完成了,这是它的最后一个线程。相信我:这个“流程结束”阶段比看起来要复杂得多,至少在你的应用程序有各种线程的情况下,它们都需要完成一些工作,并在完成这些工作时使用一些静态或全局资源。我已经分析了很多。”“结束阶段”崩溃。显式加入线程(在通知线程必须结束后)使其更易于管理。当然:如果线程是自给自足的,不使用共享资源,并且没有人关心它是在对等线程之前还是之后完成,它可以分离。