非阻塞pthread_join

Fig*_*igo 21 c multithreading pthreads

我正在对多线程服务器的关闭进行编码.如果一切顺利,所有线程都应该自行退出,但是线程卡住的可能性很小.在这种情况下,使用非阻塞连接会很方便所以我能做到.

有没有办法做一个非阻塞的pthread_join?某种定时加入也会很好.

这样的事情:

foreach thread do
  nb_pthread_join();
    if still running
      pthread_cancel();

我可以考虑更多的情况,其中一个非bloking连接将是有用的.

因为似乎没有这样的功能所以我已经编写了一个解决方法,但它并不像我想的那么简单.

yve*_*mes 22

如果您在Linux上运行应用程序,您可能有兴趣知道:

int pthread_tryjoin_np(pthread_t thread, void **retval);

int pthread_timedjoin_np(pthread_t thread, void **retval,
                                const struct timespec *abstime);
Run Code Online (Sandbox Code Playgroud)

小心,正如后缀所暗示的那样,"np"意味着"非便携式".它们不是POSIX标准,gnu扩展,虽然有用.

链接到手册页


Dav*_*rtz 10

'pthread_join'机制是一种方便使用,如果它碰巧完全符合你的要求.它没有做任何你自己无法做到的事情,并且它不是你想要的,它完全符合你的要求.

没有真正的理由你应该真正关心线程是否已经终止.你关心的是线程正在做的工作是否已经完成.要告诉它,让线程做一些事情来表明它正在工作.你如何做到这一点取决于你的具体问题的理想选择,这在很大程度上取决于线程的作用.

首先改变你的想法.这不是一个被卡住的线程,而是线程正在做的事情被卡住了.

  • @gry而不是尝试加入该线程,等待作业完成.这将你的问题简化为更简单的问题 - "我该如何等待".答案是,使用条件变量. (3认同)
  • 有一个由互斥锁保护的布尔值,用于存储您想知道的事物的状态.如果需要,使用条件变量来指示您更改布尔值. (2认同)

Fro*_*sty 1

正如其他人指出的那样,标准 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");
Run Code Online (Sandbox Code Playgroud)

在所有线程(终止与否)上调用 pthread_cancel 没有任何问题,因此为所有线程调用 pthread_cancel 不会阻塞并保证线程退出(干净与否)。

这应该算是一个“简单”的解决方法。

  • 这个答案是错误的。在每个线程上成功调用“pthread_cancel”并不能保证所有线程都已退出。它们可能还没有达到任何取消点,或者即使达到了,主线程也可能会首先被调度并从“main”返回,从而在其他线程完成清理之前杀死进程...... (25认同)