是的std ::信号和std ::提高线程安全的?(Are std::signal and std:

2019-07-19 00:41发布

C和C ++标准支持信号的概念。 然而,C11标准说函数信号()不能在多线程环境中被调用,或行为是未定义的。 但我认为信号机制本质上是多线程的环境。

从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();
}

Answer 1:

但我认为信号机制本质上是多线程的环境。

我觉得这句话是中央的误解。 signal()是用于进程间通信的方法,不用于帧间线程 。 线程共享公共存储器,因此可以通过互斥和控制结构进行通信。 进程没有共同的记忆,并与像一些明确的通信结构必须做出-做signal()或文件系统。



Answer 2:

我认为你是混乱的信号,这是具体的过程,线程间的通信。 如果共享的是你后线程之间的信息,你可能会发现你在新的想要的C ++ 11线程支持库 。 当然,这取决于你真正想做的事情。

从我可以告诉你的代码,你想一个线程“信号”在某些方面的活动,你希望能够当发出信号,事件运行一些代码。 鉴于这种情况,我会采取在线程支持库的期货部一探究竟。



Answer 3:

在C11标准的声明说:“在不确定的行为多线程程序结果使用此功能,”具体是指函数signal() 所以现在的问题是,如果使用的signal()完成“在一个多线程的程序。”

术语“多线程程序”是不是在C标准中定义的,据我所知道的,但我会带着它意味着在已创建多线程执行,并且尚未完成的程序。 这将意味着,在时间signal()被调用在您的示例程序的程序是不是多线程的,因此程序的行为没有这个要求下不确定的。

(但是C ++ 11条规定:“所有的信号处理程序应具有C键,” [18.10其他运行时支持[support.runtime] P9]。由于您的示例程序使用一个处理程序使用C ++链接的行为是不确定的。)


正如其他人所指出的信号不用于线程间的通信。 例如C和C ++标准,甚至不指定它们运行在什么的线程。 标准库,而不是提供线程间通信电子等工具,如互斥体,原子能等。



Answer 4:

我想你刚才misintrepret期限不确定的行为 ,这是不幸的是很多重载表示“不好的事情会发生。” 这里,术语真的只是说话是算数的:C标准并没有做出什么意思使用任何假设signal在多线程环境。

一般而言, signal / raise在C标准的接口并不是非常有用的本身,而是只针对平台/ OS具体的事情一个占位符,是在它的上面定义。

因此,对于之间的相互作用signal ,并威胁不给你合同。 或者换句话讲的交互signal和线程留给平台的实现。



文章来源: Are std::signal and std::raise thread-safe?