Функции
pthread
и std::condition_variable
и std::mutex
, которые используют их, не безопасны для асинхронного сигнала.См. Список безопасных асинхронных сигналов функций в man signal-safety(7)
.
Немного не по теме: если вы не блокируете мьютекс при обновлении flag
, тогда это приводитна пропущенные уведомления.Представьте себе сценарий:
Thread 1 | Thread 2
| mutex.lock()
| flag == false
flag = true |
cv.notify_one() | <--- notification is lost
| cv.wait()
Это очень распространенная ошибка программирования.
Блокировка мьютекса при обновлении flag
устраняет эту проблему.
Если вы хотите уведомить переменную условия при получении сигнала, создайте поток, предназначенный для обработки сигнала.Пример:
#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();
}
Обратите внимание, что сигналы должны быть заблокированы во всех потоках, чтобы их получали только потоки обработчика сигналов.