非阻塞pthread_join
我正在编写多线程服务器的关闭代码,如果一切正常,所有线程都应自行退出,但是线程被卡住的可能性很小,在这种情况下,进行非阻塞连接会很方便所以我可以做。
有没有一种做非阻塞pthread_join的方法?
某种定时加入也将是很好的。
像这样的东西:
foreach thread do nb_pthread_join(); if still running pthread_cancel();
我认为更多情况下使用非中断连接会很有用。
似乎没有这样的功能,所以我已经编码了一种解决方法,但是它并不像我想要的那么简单。
解决方案
回答
我们可以将字节压入作为非阻塞方式打开的管道中,以在完成操作时向另一个线程发出信号,然后使用非阻塞读取来检查管道的状态。
回答
答案确实取决于我们为什么要这样做。例如,如果我们只想清理死线程,那么最简单的方法就是让一个"死线程清理器"线程循环并连接。
回答
我不确定确切意思,但是我假设我们真正需要的是等待通知机制。
简而言之,它是这样工作的:我们等待条件满足超时。在以下情况下,等待将结束:
- 发生超时,或者
- 如果条件满足。
我们可以循环执行此操作,并为逻辑添加更多智能。我找到的与此Pthreads相关的最佳资源是本教程:
POSIX线程编程(https://computing.llnl.gov/tutorials/pthreads/)。
我也很惊讶地发现Pthreads中没有用于定时连接的API。
回答
没有定时的pthread_join
,但是如果我们正在等待其他有条件的线程阻塞,则可以使用定时的pthread_cond_timed_wait
代替pthread_cond_wait
回答
如果我们正在开发QNX,则可以使用pthread_timedjoin()函数。
否则,我们可以创建一个单独的线程,该线程将执行pthread_join()并通过发出信号量(例如,子线程已完成)来警告父线程。这个单独的线程可以返回从pthread_join()获得的结果,以使父线程不仅可以确定子进程何时完成,还可以确定其返回的值。
回答
正如其他人指出的那样,标准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并没有错,因此对所有线程进行调用都不会阻塞,并且可以保证线程退出(干净与否)。
那应该算是"简单"的解决方法。
回答
如果我们在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扩展,但很有用。
链接到手册页