Сводка
Я пытался закодировать симуляцию Монте-Карло, которая включает в себя до нескольких основных процессов. Через некоторое время родитель отправляет SIGUSR1 всем дочерним элементам, которые затем должны прекратить вычислять результаты отправки обратно родителю.
Когда я компилирую без какой-либо оптимизации (clang thread_stop.c
), поведение будет таким, как ожидалось. Когда я пытаюсь оптимизировать код (clang -O1 thread_stop.c
), сигналы перехватываются, но дети не останавливаются.
Код
Я сокращаю код до мельчайшего фрагмента, который ведет себя так же :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h> /* pid_t */
#include <sys/mman.h> /* mmap */
#define MAX 1 /* Max time to run */
static int a=0; /* int to be changed when signal arrives */
void sig_handler(int signo) {
if (signo == SIGUSR1){
a=1;
printf("signal caught\n");
}
}
int main(void){
int * comm;
pid_t pid;
/* map to allow child processes access same array */
comm = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
*comm = 0;
pid=fork();
if(pid == 0){ /* child process */
signal(SIGUSR1, sig_handler); /* catch signal */
do {
/* do things */
} while(a == 0);
printf("Child exit(0)\n");
*comm = 2;
exit(0); /* exit for child process */
} /* if(pid == 0) - code below is parent only */
printf("Started child process, sleeping %d seconds\n", MAX);
sleep(MAX);
printf("Send signal to child\n");
kill(pid, SIGUSR1); /* send SIGUSR1 */
while(*comm != 2) usleep(10000);
printf("Child process ended\n");
/* clean up */
munmap(comm, sizeof(int));
return 0;
}
Система
clang показывает это на termux (clang 9.0.1) и lubuntu (clang 6.0.0-lubuntu2).