Летучие, std :: sig_atomic_t и atomic_signal_fence

Пример

#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);
}

Я пытаюсь понять несколько вещей:

  1. Правильно ли вообще объявлять переменную с типом std::sig_atomic_t без volatile? Учитывая, что переменная совместно используется обработчиком и потоком - точно так же, как gSignalStatus выше, но без volatile. Согласно ответу эта почта, кажется, требуется volatile.
  2. Согласно стандарту C++:

    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!

Спасибо!

volatile не имеет отношения к многопоточности.
Jarod42 24.07.2018 15:55

Обратите внимание, что связанный с вами вопрос относится к C и относится к стандарту C, в то время как ваш вопрос помечен как C++ и явно является кодом C++. Я не могу сказать, одинаковы ли C и C++ в этой ситуации, но есть большая вероятность, что это не так.

Fred Larson 24.07.2018 15:57

@ Jarod42 да. volatile должен сообщить компилятору, что переменная может быть изменена способом, не определенным в стандарте. Но спецификация C++ просто упоминает volatile std::sig_atomic_t один раз без указания, необходим ли volatile, или только std::sig_atomic_t неявно содержит volatile, или только std::sig_atomic_t, вероятно, будет иметь неопределенное поведение и т. д.

HCSF 24.07.2018 16:00

@FredLarson да, мой вопрос касается C++, а не C. Я связался с сообщением с цитатой из стандарта C99. Я знаю, что это не совсем так, но стандарт C++ не говорит много о std::sig_atomic_t с volatile; поэтому я просто попытался связать свой вопрос со стандартом C, чтобы увидеть, подразумевается ли он или что-то в этом роде.

HCSF 24.07.2018 16:02
std::atomic<int> gSignalStatus = 0; - правильный путь.
Jarod42 24.07.2018 16:02

страница cppreference на sig_atomic_t для C++ интересен, но, кажется, излишне лаконичен.

Fred Larson 24.07.2018 16:05

@ Jarod42 на основе этого Почта, кажется, что std::sig_atomic_t нельзя заменить на std::atomic в некоторых случаях (конечно, если параметр шаблона - int, они взаимозаменяемы), но также кажется, что std::sig_atomic_t является предпочтительным типом для использования в обработчике сигналов, нет?

HCSF 24.07.2018 16:07

По вашей ссылке, volatile необходим для sig_atomic_t в случае "обработки" сигнала.

Jarod42 24.07.2018 16:12
std::signal содержит много полезных сведений об изменениях в использовании между версиями C++.
anonymous 24.07.2018 17:32

FredLarson jon-harper благодарит за ссылки. Если я правильно помню, люди, использующие stackoverflow, находили различные ошибки на cppreference.com; так что это просто не надежный источник, по крайней мере, для меня. ржу не могу

HCSF 25.07.2018 04:32
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
10
666
1

Ответы 1

В вашем конкретном случае использования может быть более энергоэффективным и целесообразным использовать функцию sigwait. Никаких volatile или std::atomic не требуется.

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

HCSF 25.07.2018 04:29

Другие вопросы по теме