Я понимаю, что единственное, что может сделать обработчик сигналов в 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()
в обработчике сигнала (corrct меня, если я ошибаюсь) - Сигнал мог поступать как раз между проверкой на
doWait
, и когда нить идет спать, поэтому она никогда не проснется (очевидно, я не могу заблокировать мьютекс в сигнале Хандера, чтобы этого избежать).
До сих пор единственным решением, я могу видеть это реализовать занят ожидания на переменной doWait
(вероятно, спать в течение нескольких миллисекунд в каждой итерации), который поражает меня как весьма неэффективно.
Обратите внимание, что хотя моя программа выше имеет только один поток, я назвал свой вопрос многопоточным, потому что речь идет о примитивах управления потоками. Если в стандартном C++ нет решения, я бы согласился принять решение с использованием конкретных функций Linux/POSIX.
Спасибо. Этого я боялся (хотя я не знал полного списка доступных механизмов Linux/Posix). Я очень надеюсь, что однажды мы сможем получить семафоры в стандарт. – MikeMB