Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/248.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::condition\u变量::notify\u是可重入的吗?_C++_Signals_Atomic_Condition Variable_Sigint - Fatal编程技术网

C++ std::condition\u变量::notify\u是可重入的吗?

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

我可以安全地执行以下代码吗?这里是否可能出现死锁或一些意外行为,特别是当SIGINT到达时

#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()就足够了。@MOJNICK
wait(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();
}