是 std::signal 和 std::raise 线程安全的
Are std::signal and std::raise thread-safe?
>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();
}
但我认为信号机制本质上是针对多线程环境的。
我认为这句话是中心误解。 signal()
是一种用于进程间通信的方法,而不是用于线程间通信的方法。线程共享公共内存,因此可以通过互斥锁和控制结构进行通信。进程没有公共内存,必须使用一些显式通信结构(如signal()
或文件系统)。
我认为您将特定于进程的信号与线程之间的通信混淆了。如果要在所追求的线程之间共享信息,则可能会在新的 C++11 线程支持库中找到所需的内容。当然,这取决于你真正想做什么。
从我能告诉你的代码来看,你希望一个线程以某种方式"发出"事件信号,并且你希望能够在该事件发出信号时运行一些代码。鉴于此,我会仔细查看线程支持库中的"期货"部分。
C11 标准的声明"在多线程程序中使用此函数会导致未定义的行为",特指函数signal()
。所以问题是signal()
的使用是否是"在多线程程序中"完成的。
我所知,术语"多线程程序"在 C 标准中没有定义,但我认为它是指已创建多个执行线程但尚未完成的程序。这意味着在示例程序中调用signal()
时,该程序不是多线程的,因此程序的行为在此要求下不是未定义的。
(但是C++11要求"所有信号处理程序都应具有C链接"[18.10其他运行时支持[support.runtime] p9]。由于示例程序使用具有C++链接的处理程序,因此行为未定义。
正如其他人指出的那样,信号不适用于线程之间的通信。例如,C 和 C++ 标准甚至没有指定它们在哪个线程上运行。相反,标准库提供了其他用于线程间通信的工具,例如互斥体、原子组学等。
我认为你只是误解了术语未定义的行为,不幸的是,它被重载到意味着"坏事会发生"。在这里,该术语实际上只是意味着它所说的:C 标准没有对在多线程上下文中使用signal
的含义做出任何假设。
通常,C标准中的signal
/raise
接口本身并不是很有用,而只是在其上定义的平台/OS特定事物的占位符。
因此,对于signal
和威胁之间的交互,不会给你一个合同。或者另有说明,signal
和线程的交互留给平台实现。
- 通过网络、跨平台传递std::变体是否安全
- 在std::thread中,joinable()然后join()线程安全吗
- 使用std::istream::peek()总是安全的吗
- 在什么条件下使用 std::memcpy 在对象之间复制是安全的?
- std::memmove在同一对象之间是否始终安全
- 从其存储的回调中删除 std::函数是否安全
- 使用 std::vector::swap 方法在C++中交换两个不同的向量是否安全?
- 我可以对 std::array 使用自定义分配器来获取安全加密密钥吗?
- 安全回调提供程序(SFINAE,std::正向和过载解析)
- 如果迭代器没有因插入而无效,则使用std::find和C::insert()是线程安全的
- std::weak_ptr<T>::锁定线程安全吗?
- std::shared_ptr::unique(),复制和线程安全
- 通过std::shared_ptr使用Rcpp和RcppParallel的线程安全函数指针
- 附加类型安全的子类std::string
- 我们如何使std::uniform_int_distribution加密安全
- std::mutex作为一个成员变量对多个线程来说是安全的吗
- std::free线程安全吗
- 为什么我的 std::atomic<int> 变量不是线程安全的?
- 访问"std::vector"的保留但未调整大小的内存作为原始内存是否安全?
- c++类用STD安全指针相互链接(c++)