我正在编写多线程服务器的关闭代码。如果一切顺利,所有线程都应该自行退出,但是线程卡住的可能性很小。在这种情况下,使用非阻塞连接会很方便所以我可以做到。
有没有办法进行非阻塞 pthread_join?某种定时加入也会很好。
像这样的东西:
foreach 线程做 nb_pthread_join(); 如果还在运行 pthread_cancel();
我可以想到更多非阻塞连接有用的情况。
似乎没有这样的功能,所以我已经编写了一个解决方法,但这并不像我想要的那么简单。
我正在编写多线程服务器的关闭代码。如果一切顺利,所有线程都应该自行退出,但是线程卡住的可能性很小。在这种情况下,使用非阻塞连接会很方便所以我可以做到。
有没有办法进行非阻塞 pthread_join?某种定时加入也会很好。
像这样的东西:
foreach 线程做 nb_pthread_join(); 如果还在运行 pthread_cancel();
我可以想到更多非阻塞连接有用的情况。
似乎没有这样的功能,所以我已经编写了一个解决方法,但这并不像我想要的那么简单。
如果您在 Linux 上运行您的应用程序,您可能有兴趣知道:
int pthread_tryjoin_np(pthread_t thread, void **retval);
int pthread_timedjoin_np(pthread_t thread, void **retval,
const struct timespec *abstime);
请注意,正如后缀所暗示的那样,“np”表示“不可移植”。它们不是 POSIX 标准,gnu 扩展,但很有用。
'pthread_join' 机制是一种方便使用,如果它恰好做你想要的。它不会做任何你自己做不到的事情,如果它不完全是你想要的,那么你就可以编写你想要的代码。
没有真正的理由您应该真正关心线程是否已终止。你关心的是线程正在做的工作是否完成。为了说明这一点,让线程做一些事情来表明它正在工作。您如何做到这一点取决于您的特定问题的理想选择,这在很大程度上取决于线程在做什么。
从改变你的想法开始。不是线程卡住了,而是线程正在做什么卡住了。
如果您正在为 QNX 开发,您可以使用 pthread_timedjoin() 函数。
否则,您可以创建一个单独的线程来执行 pthread_join() 并警告父线程,例如通过信号量发出子线程完成的信号。这个单独的线程可以返回从 pthread_join() 获取的内容,让父线程不仅可以确定子线程何时完成,还可以确定它返回的值。
答案实际上取决于您为什么要这样做。例如,如果您只想清理死线程,那么最简单的方法就是拥有一个循环和连接的“死线程清理器”线程。
我不确定你到底是什么意思,但我假设你真正需要的是等待和通知机制。
简而言之,它是这样工作的:您等待一个条件满足超时。如果出现以下情况,您的等待将结束:
您可以循环使用它并为您的逻辑添加更多智能。我找到的与 Pthreads 相关的最佳资源是本教程:POSIX 线程编程(https://computing.llnl.gov/tutorials/pthreads/)。
我也很惊讶地看到 Pthreads 中没有用于定时连接的 API。
没有 timed pthread_join
,但是如果您正在等待其他线程在条件上阻塞,您可以使用 timedpthread_cond_timed_wait
代替pthread_cond_wait
正如其他人指出的那样,标准 pthread 库中没有非阻塞 pthread_join 可用。
但是,鉴于您陈述的问题(试图保证所有线程在程序关闭时都已退出),不需要这样的功能。你可以简单地这样做:
int killed_threads = 0;
for(i = 0; i < num_threads; i++) {
int return = pthread_cancel(threads[i]);
if(return != ESRCH)
killed_threads++;
}
if(killed_threads)
printf("%d threads did not shutdown properly\n", killed_threads)
else
printf("All threads exited successfully");
在所有线程(终止与否)上调用 pthread_cancel 没有任何问题,因此为所有线程调用它不会阻塞并保证线程退出(干净与否)。
这应该是一个“简单”的解决方法。
您可以将一个字节推送到以非阻塞方式打开的管道中,以便在完成时向另一个线程发出信号,然后使用非阻塞读取来检查管道的状态。