2 вопроса (ниже) о статической инициализации C ++ 11 в [1] в этом справочном коде (это полный протестированный пример программы на c ++ 11).
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
struct Foo {
/* complex member variables. */
};
void DoSomething(Foo *foo) {
// Complex, but signal safe, use of foo.
}
Foo InitFoo() {
Foo foo;
/* complex, but signal safe, initialization of foo */
return foo;
}
Foo* GetFoo() {
static Foo foo = InitFoo(); // [1]
return &foo;
}
void Handler(int sig) {
DoSomething(GetFoo());
}
int main() {
// [2]
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_handler = Handler;
sigaction(SIGINT, &act, nullptr);
for (;;) {
sleep(1);
DoSomething(GetFoo());
}
}
Вопрос1: Это гарантированно безопасно (без тупиков и т. Д.)? C ++ 11 статическая инициализация включает в себя блокировки. Что если сигнал доставляется до / после / во время первого вызова GetFoo () в main?
Вопрос2: Это гарантированно безопасно, если вызов GetFoo () вставлен в [2] до установки обработчика сигнала?
Я предполагаю, что C ++ 11 (g ++ или clang) на последних версиях GNU / Linux, хотя ответы на различные Unices также были бы интересны. (Спойлер: я думаю, что ответ 1: НЕТ и 2: ДА, но я не знаю, как это доказать.)