C和C ++标准支持信号的概念。但是,C11标准表示无法在多线程环境中调用函数signal(),或者行为未定义。但我认为信号机制本质上适用于多线程环境。
C11标准7.14.1.1.7的引用
“在多线程程序中使用此函数会导致未定义的行为 实现应该表现得好像没有库函数调用信号函数。“
对此有何解释?
以下代码不言而喻。
#include <thread>
#include <csignal>
using namespace std;
void SignalHandler(int)
{
// Which thread context here?
}
void f()
{
//
// Running in another thread context.
//
raise(SIGINT); // Is this call safe?
}
int main()
{
//
// Register the signal handler in main thread context.
//
signal(SIGINT, SignalHandler);
thread(f).join();
}
答案 0 :(得分:16)
我认为这句话是中心的误解。但我认为信号机制本质上适用于多线程环境。
signal()
是一种进行进程通信的方法,而不是用于线程的方法。线程共享公共内存,因此可以通过互斥锁和控制结构进行通信。进程没有公共内存,必须使用某些显式通信结构(如signal()
或文件系统)进行处理。
答案 1 :(得分:4)
我认为你混淆信号,这是特定于流程的,线程之间的通信。如果它是您之后的线程之间共享信息,您可能会在新的C++11 thread support library中找到您想要的内容。当然,这取决于你真正想做的事情。
从我所知道的代码中,您希望线程以某种方式“发出信号”事件,并且您希望能够在发出该事件信号时运行一些代码。鉴于此,我将仔细研究线程支持库中的Futures部分。
答案 2 :(得分:2)
C11标准的声明“在多线程程序中使用此函数会导致未定义的行为”,特指函数signal()
。所以问题是如果在多线程程序中使用signal()
。“
就我所知,术语“多线程程序”在C标准中没有定义,但我认为这意味着一个程序,其中已经创建了多个执行线程但尚未完成。这意味着在您的示例程序中调用signal()
时,程序不是多线程的,因此在此要求下程序的行为不是未定义的。
(但是C ++ 11要求“所有信号处理程序都应具有C链接”, [18.10其他运行时支持[support.runtime] p9] 。因为您的示例程序使用带有C ++的处理程序联系行为未定义。)
正如其他人所指出的那样,信号不是用于线程之间的通信。例如,C和C ++标准甚至没有指定它们运行的线程。标准库提供了其他用于线程间通信的工具,例如互斥,原子等。
答案 3 :(得分:1)
我认为你只是错误地表达了未定义的行为一词,不幸的是,这意味着很多重载意味着&#34;坏事将会发生&#34;。这里的术语实际上只是意味着它:C标准没有假设在多线程环境中使用signal
意味着什么。
通常,C标准中的signal
/ raise
接口本身并不是非常有用,但只是在其上定义的平台/操作系统特定事物的占位符。
因此signal
与威胁之间的互动并不能给你一份合同。或者另有说明,signal
和线程的交互留给平台
实施