你如何查询pthread以查看它是否仍在运行?

Tre*_*ith 52 c concurrency multithreading destructor pthreads

在我的析构函数中,我想干净地销毁一个线程.

我的目标是等待线程完成执行然后破坏线程.

我发现查询pthread状态的唯一事情是pthread_attr_setdetachstate,但这只会告诉你你的线程是:

  • PTHREAD_CREATE_DETACHED
  • PTHREAD_CREATE_JOINABLE

这两者都与线程是否仍在运行无关.

你如何查询pthread以查看它是否仍在运行?

jer*_*ble 41

听起来你有两个问题:

我怎么能等到我的线程完成?

答:这是由pthreads直接支持的 - 使你的线程可以停止JOINABLE(首次启动时),并使用pthread_join()阻止当前线程,直到不再停止线程为止运行.


如何判断我的线程是否仍在运行?

答:您可以添加"thread_complete"标志来执行此操作:

场景:线程A想知道线程B是否仍然存在.

创建线程B时,会给它一个指向"thread_complete"标志地址的指针.在创建线程之前,应将"thread_complete"标志初始化为NOT_COMPLETED.线程B的入口点函数应立即调用pthread_cleanup_push()来推送一个"清理处理程序",它将"thread_complete"标志设置为COMPLETED.

在此处查看有关清理处理程序的详细信息:pthread清理处理程序

你需要包含一个相应的pthread_cleanup_pop(1)调用,以确保无论如何调用清理处理程序(即如果线程正常退出或由于取消等).

然后,线程A可以简单地检查"thread_complete"标志以查看线程B是否已经退出.

注意:您的"thread_complete"标志应声明为"volatile"且应为原子类型 - GNU编译器为此提供sig_atomic_t.这允许两个线程一致地访问相同的数据,而不需要同步构造(互斥/信号量).

  • 清除处理程序是完全没有必要的,除非你将使用取消(这通常是一个相当危险的工具).此外,您可能希望使用pthread条件变量以及标志变量来启用等待而不会旋转和刻录cpu循环. (2认同)

小智 31

pthread_kill(tid, 0);
Run Code Online (Sandbox Code Playgroud)

没有信号被发送,但仍然执行错误检查,因此您可以使用它来检查tid的存在.

注意:此答案不正确.该标准明确禁止传递其生命周期结束的线程的ID.该ID现在可能指定不同的线程,或者更糟糕的是,它可能引用已释放的内存,从而导致崩溃.

  • 对于我的问题,这正是我需要解决的问题,谢谢。我使用了(pthread_kill(tid,0)!= ESRCH)。 (2认同)
  • 请注意:http://stackoverflow.com/questions/1693180/how-do-i-determine-if-a-pthread-is-alive (2认同)

Jer*_*ner 8

我认为你真正需要的是调用pthread_join().在线程退出之前,该调用不会返回.

如果你只想轮询以查看线程是否仍在运行(并注意通常不是你想要做的那样!),你可以让线程在它退出之前将volatile布尔值设置为false.那么你的主线程可以读取布尔值,如果它仍然是真的,你知道线程仍在运行.(如果它是假的,另一方面,你知道线程至少几乎消失了;它可能仍在运行清除代码,它在布尔值设置为false之后发生,所以即使在这种情况下你仍然应该调用pthread_join之前试图释放线程可能有权访问的任何资源)

  • "那么你的主线程可以读取布尔值,如果它仍然是真的,你知道线程仍在运行." - 在这种情况下,您只能知道线程是否已经干净地退出,这与仍然运行的不同. (2认同)
  • 嗯,我可能在这里错过了一个可能性,但AFAICT线程要么仍然在运行,要么已经退出,或者它已经崩溃了.如果线程已崩溃,则使用它进行剩余的处理,因此无论如何都没有第二个线程可以检测到它. (2认同)

Dew*_*wfy 5

没有完全可移植的解决方案,看看您的平台是否支持pthread_tryjoin_np或pthread_timedjoin_np.所以你只需要检查线程是否可以连接(当然是用PTHREAD_CREATE_JOINABLE创建的).