Пример
#include <csignal>
#include <cstdio>
#include <cstdlib>
volatile std::sig_atomic_t gSignalStatus = 0;
void signal_handler(int signal) {
gSignalStatus = signal;
}
int main() {
// Install a signal handler
std::signal(SIGTERM, signal_handler);
while (gSignalStatus == 0) {}
printf("%d\n", gSignalStatus);
}
Я пытаюсь понять несколько вещей:
std::sig_atomic_t без volatile? Учитывая, что переменная совместно используется обработчиком и потоком - точно так же, как gSignalStatus выше, но без volatile. Согласно ответу эта почта, кажется, требуется volatile.extern "C" void atomic_signal_fence(memory_order order) noexcept; 6 Effects: Equivalent to atomic_thread_fence(order), except that the resulting ordering constraints are established only between a thread and a signal handler executed in the same thread.
похоже, что спецификация предполагает, что обработчик сигнала может быть вызван любым потоком, и поэтому atomic_signal_fence добавлен в спецификацию? Но в приведенной выше спецификации также упоминается «тот же поток». Следовательно, я сбит с толку. На моей машине обработчик сигнала вызывается основным потоком. Было бы неплохо привести пример, иллюстрирующий необходимость atomic_signal_fence!
Спасибо!
Обратите внимание, что связанный с вами вопрос относится к C и относится к стандарту C, в то время как ваш вопрос помечен как C++ и явно является кодом C++. Я не могу сказать, одинаковы ли C и C++ в этой ситуации, но есть большая вероятность, что это не так.
@ Jarod42 да. volatile должен сообщить компилятору, что переменная может быть изменена способом, не определенным в стандарте. Но спецификация C++ просто упоминает volatile std::sig_atomic_t один раз без указания, необходим ли volatile, или только std::sig_atomic_t неявно содержит volatile, или только std::sig_atomic_t, вероятно, будет иметь неопределенное поведение и т. д.
@FredLarson да, мой вопрос касается C++, а не C. Я связался с сообщением с цитатой из стандарта C99. Я знаю, что это не совсем так, но стандарт C++ не говорит много о std::sig_atomic_t с volatile; поэтому я просто попытался связать свой вопрос со стандартом C, чтобы увидеть, подразумевается ли он или что-то в этом роде.
std::atomic<int> gSignalStatus = 0; - правильный путь.
страница cppreference на sig_atomic_t для C++ интересен, но, кажется, излишне лаконичен.
@ Jarod42 на основе этого Почта, кажется, что std::sig_atomic_t нельзя заменить на std::atomic в некоторых случаях (конечно, если параметр шаблона - int, они взаимозаменяемы), но также кажется, что std::sig_atomic_t является предпочтительным типом для использования в обработчике сигналов, нет?
По вашей ссылке, volatile необходим для sig_atomic_t в случае "обработки" сигнала.
std::signal содержит много полезных сведений об изменениях в использовании между версиями C++.
FredLarson jon-harper благодарит за ссылки. Если я правильно помню, люди, использующие stackoverflow, находили различные ошибки на cppreference.com; так что это просто не надежный источник, по крайней мере, для меня. ржу не могу





В вашем конкретном случае использования может быть более энергоэффективным и целесообразным использовать функцию sigwait. Никаких volatile или std::atomic не требуется.
Дать согласие. Пример приведен только для иллюстрации. Моя основная цель - попытаться найти ответы на 2 заданных мной вопроса, чтобы я мог правильно и эффективно использовать std :: signal. В моем реальном приложении мой основной поток запускает жесткий цикл для выполнения работы и будет выполнять очистку и выходить из цикла, если обнаружен SIGTERM.
volatileне имеет отношения к многопоточности.