C++ std::condition\u变量::notify\u是可重入的吗?
我可以安全地执行以下代码吗?这里是否可能出现死锁或一些意外行为,特别是当SIGINT到达时C++ std::condition\u变量::notify\u是可重入的吗?,c++,signals,atomic,condition-variable,sigint,C++,Signals,Atomic,Condition Variable,Sigint,我可以安全地执行以下代码吗?这里是否可能出现死锁或一些意外行为,特别是当SIGINT到达时 #include <atomic> #include <condition_variable> #include <csignal> std::mutex m; std::condition_variable cv; std::atomic<bool> flag(false); void f1(){ std::signal(SI
#include <atomic>
#include <condition_variable>
#include <csignal>
std::mutex m;
std::condition_variable cv;
std::atomic<bool> flag(false);
void f1(){
std::signal(SIGTERM, [](int signal){flag.store(true,
std::memory_order_release); cv.notify_one();});//register for signal
std::unique_lock<std::mutex> mtx(m);
cv.wait(mtx, []{return flag.load(std::memory_order_consume);});//wait for signal or f2() notify
}
void f2(){
flag.store(true, std::memory_order_release);
cv.notify_one();
}
int main(){
std::thread th1(f1);
std::thread th2(f2);
th1.join();
th2.join();
return 0;
}
#包括
#包括
#包括
std::互斥m;
std::条件变量cv;
std::原子标志(假);
void f1(){
std::信号(SIGTERM,[](int-signal){flag.store(true,
std::memory_order_release);cv.notify_one();})//为信号注册
标准:唯一锁定mtx(m);
cv.wait(mtx,[{return flag.load(std::memory_order_consume);})//等待信号或f2()通知
}
无效f2(){
flag.store(true,std::memory\u order\u release);
cv.通知_one();
}
int main(){
标准:螺纹th1(f1);
标准:螺纹th2(f2);
th1.join();
th2.join();
返回0;
}
pthread
函数和std::condition\u变量
和std::mutex
使用这些函数和函数的异步信号安全。请参阅中的异步信号安全函数列表
有点离题:如果在更新标志时未锁定互斥锁,则会导致错过通知。想象一下场景:
Thread 1 | Thread 2
| mutex.lock()
| flag == false
flag = true |
cv.notify_one() | <--- notification is lost
| cv.wait()
请注意,必须在所有线程中阻止这些信号,以便只有信号处理程序线程接收这些信号。丢失通知很好,但不是根据等待(lock,predicate())-如果predicate()在开始时返回true,它会立即返回(这里的标志==true)。()你对信号屏蔽有什么看法?在这种情况下,在f2()中调用std::raise(SIGTERM)而不是cv.notify()就足够了。@MOJNICKwait(lock,predicate())
does而(!predicate())cv.wait(lock)代码>为您循环。当更新了谓词
并且在该检查之后但在cv.wait(lock)
之前发出通知时,通知将丢失。不幸的是,等待(lock,predicate())
中没有魔法。我希望您能回答两个问题:1。是而(!flag)cv.wait(lock)
与cv.wait(lock,[{return flag;})完全相同代码>?2.在signal\u thread()
中,我是否可以使用std::atomic
而不是bool flag
和mutex m
锁定机制?谢谢你。@mojnick1。它是。2.不,您可以使用atomic
或mutex
,但不能同时使用两者。
#include <condition_variable>
#include <iostream>
#include <thread>
#include <signal.h>
std::mutex m;
std::condition_variable cv;
bool flag = false;
void f1(){
std::unique_lock<std::mutex> lock(m);
while(!flag)
cv.wait(lock);
}
void signal_thread() {
sigset_t sigset;
sigfillset(&sigset);
int signo = ::sigwaitinfo(&sigset, nullptr);
if(-1 == signo)
std::abort();
std::cout << "Received signal " << signo << '\n';
m.lock();
flag = true;
m.unlock();
cv.notify_one();
}
int main(){
sigset_t sigset;
sigfillset(&sigset);
::pthread_sigmask(SIG_BLOCK, &sigset, nullptr);
std::thread th1(f1);
std::thread th2(signal_thread);
th1.join();
th2.join();
}