Can I safely execute following code? Is it possible to have deadlock here or some unexpected behaviour, especially when SIGINT arrives?
#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;
}
pthread
functions and std::condition_variable
and std::mutex
which use those are not async-signal safe. See the list of async-signal safe functions in man signal-safety(7)
.
A bit off-topic: if you do not lock the mutex when updating flag
then that leads to missed notifications. Imagine scenario:
Thread 1 | Thread 2
| mutex.lock()
| flag == false
flag = true |
cv.notify_one() | <--- notification is lost
| cv.wait()
This is a very common programming mistake.
Locking the mutex when updating flag
fixes this problem.
If you would like to notify a condition variable when a signal is received create a thread dedicated to signal handling. Example:
#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();
}
Note that the signals must be blocked in all threads, so that only the signal handler threads receives those.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.