执行std::thread::join()时的SIGINT

SIGINT while doing std::thread::join()

本文关键字:时的 SIGINT join std thread 执行      更新时间:2023-10-16

我有一个main(),它生成一个线程,然后连接到它。我希望能够CTRL-C程序,所以我会在main中安装SIGINT处理程序(派生线程将忽略此信号)。当我在sig处理程序中时,我将用cancel()取消派生的线程,但当前的"join()"会发生什么,它在信号调用期间是活动的。我的猜测是,我会得到EAGAIN或EINTR,并且我必须在循环中生成join()。我说得对吗?非常感谢。

问题是:这对多重阅读合法吗。我不介意在SIGINT句柄中设置一个标志,但是join()调用会发生什么呢?

信号和线程?龙来了!您必须完全指定掩码,否则任何线程都可能接收到信号。

信号处理程序通常不应假定它在"主"线程中运行。相反,它应该发布一条消息并返回,类似于线程中断。主线程可以在稍后的事件循环或其他事件中接收到这一点,然后加入。

std::thread::join()具有void返回类型,因此无法返回EINTR。在POSIX平台上,它可能是pthread_join的包装器,它不返回EINTR。连接线程不应返回或抛出,直到线程成功连接,前提是它是在可连接线程上调用的。

顺便说一句,从信号处理程序中取消线程可能不安全。std::thread没有cancel()成员函数,所以我认为您已经编写了自己的函数。因此,您需要检查它在信号处理程序中使用是否安全——例如,pthread_cancel()没有被列为可以从信号处理程序安全调用的函数。