对矢量(vector::operator[]和vector:(size))的只读访问是异步安全的
Is read-only access to a vector (vector::operator[] and vector::size()) asynchronous-safe?
我的程序需要在SIGINT
的信号处理程序中对vector<string>
的内容执行只读访问。(另一种选择是使用固定长度的C字符串的固定大小数组。)该程序被设计为在POSIX环境中运行。
vector::operator[]
和vector::size()
异步安全(或信号安全)吗?
不,它不安全。C++11 1.9/6:
当抽象机器的处理因接收到信号而中断时都不是
volatile std::sig_atomic_t
型- 无锁原子对象(29.4)
在执行信号处理程序期间未指定,并且不在其中任何一个中的任何对象的值处理程序修改的两个类别变为未定义类别。
如果进程是多线程的,或者如果进程是单线程的,并且执行的信号处理程序不是的结果
调用
abort()
、raise()
、kill()
、pthread_kill()
或sigqueue()
以生成未阻塞的信号的过程一个挂起的信号被解除阻塞,并在解除阻塞的呼叫之前发送,它返回
如果信号处理程序引用除
errno
之外的具有静态存储持续时间的任何对象,而不是通过将值分配给声明为volatile sig_atomic_t
的对象,或者信号处理程序调用本标准中定义的除下表中列出的函数之一之外的任何函数,则行为是未定义的。
来源:开放式集团基础规范第7期IEEE Std 1003.1,2013版,2.4.3
这…仍然是一个非常薄弱的保证。据我所知:
vector::operator[]
不安全固定数组不安全如果数组是非静态的,那么访问固定数组是安全的
为什么?vector::operator[]
并没有具体说明它应该如何实现,只有先决条件和后决条件。访问数组的元素是可能的(如果数组是非静态的),这意味着如果在发信号之前创建一个指针(使用vec.data()
或&vec[0]
),然后通过指针访问元素,那么访问向量元素也是安全的。
编辑:最初我错过了这个,因为我不知道sigaction
函数——使用signal
,你只能在信号处理程序中访问本地数组,但使用sigaction
,你可以提供指向自动和动态数组的指针。不过,在信号处理程序中尽可能少做的建议仍然适用于此。
一句话:你在信号处理程序上做得太多了。尽量少做。一种方法是分配给一个标志(类型为volatile sig_atomic_t
),然后返回。代码稍后可以检查标志是否被触发(例如在事件循环中)
我相信,如果您知道访问向量不安全的原因,那么您可以解决它。请注意,访问仍然不能保证安全。但它将适用于任何不是死亡站9000的东西。
信号处理程序中断程序的执行,就像直接对硬件进行编程时的中断处理程序一样。操作系统只是简单地停止执行您的程序,无论它在哪里。这可能是在任何事情的中间。例如,如果向量中添加了元素,并且正在更新其大小值,或者正在将内容复制到一个新的、更长的向量中,则该向量可能会被信号中断。然后,您的信号处理程序将尝试从向量中读取,从而导致灾难。
您可以从信号处理程序访问向量,只要它实际上是常量。如果你在程序启动时设置了整个程序,然后再也不写,那么使用它是安全的。注意,根据标准文件使用不安全,但有效安全。
这很像单核CPU上的多线程。
现在,如果你确实需要在程序运行时更新向量,你需要在更新向量之前通过屏蔽信号或禁用处理程序来"锁定"信号处理程序,以确保在向量处于不一致状态时处理程序不会运行。
- 使用 std::vector::swap 方法在C++中交换两个不同的向量是否安全?
- 访问"std::vector"的保留但未调整大小的内存作为原始内存是否安全?
- std::vector::clear()ing 二维向量线程的内部向量安全吗?
- 使用 std::vector<char> 作为异构记录的存储是否安全?
- 使用 std::vector,为什么 &vec[0] 未定义的行为,而 vec.data() 是安全的?
- 实现 std::vector::p ush_back 强异常安全
- 将分配到std :: vector元素线程安全
- 使用具有不同整数类型的 std::vector 是否始终安全<size_t>?
- 返回 vector<T><auto_ptr> 是否安全?
- std::vector::擦除异常安全
- 安全使用 vector.emplace_back( 新的 MyPointer );矢量内部的故障是否会导致内存泄漏
- std::vector 不是异常安全的
- 将两个 std::vector<cv::P oint> 向量和安全公共点与第三个 std::vector<cv::P oint 进行比较>
- 对矢量(vector::operator[]和vector:(size))的只读访问是异步安全的
- 使用 std::vector<T*> 是否不如 std::vector<shared_ptr<T>> 安全?
- c++中Vector = Vector的浮点错误安全
- 我可以制作一个线程安全的 std::atomic<vector<int>>吗?
- std::map和std::vector线程安全吗?
- std::vector<>::emplace_back() 中的异常安全?
- 在vector上迭代时使用return语句退出循环是否安全?