我知道,在ISO/C++11中,信号处理程序只允许读取或写入无锁原子变量或volatile sig_atomic_t
(我认为,POSIX允许调用一些系统函数)。
我想知道,是否有任何方法可以唤醒正在等待条件变量的线程。也就是说:
#include <mutex>
#include <atomic>
#include <condition_variable>
std::mutex mux;
std::condition_variable cv;
std::atomic_bool doWait{ true };
void signalHandler(int){
doWait = false;
cv.notify_one();
}
int main() {
//register signal handler
//Do some stuff
{//wait until signal arrived
std::unique_lock<std::mutex> ul(mux);
cv.wait(ul, []{return !doWait; });
}
//Do some more stuff
}
这至少存在两个问题:
- 我认为,在信号处理程序中不允许调用
notify_one()
(如果我错了,请纠正我) - 信号可能恰好在检查
doWait
和线程进入睡眠状态之间到达,因此它永远不会醒来(显然,我无法在信号处理程序中锁定互斥量以避免这种情况)。
到目前为止,我能看到的唯一解决方案是在doWait
变量上实现忙等待(可能在每次迭代中睡眠几毫秒),这使我感觉相当低效。
请注意,即使我的程序只有一个线程,我也将我的问题标记为多线程,因为它涉及线程控制原语。如果在标准C++中没有解决方案,我愿意接受使用Linux/POSIX特定函数的解决方案。