Я пишу программу на C, которая делает следующее:
Отслеживает, какие сигналы на него отправляются. Подсчитывает, сколько раз были отправлены SIGUSR1 и SIGUSR2. Завершает, когда SIGTERM был отправлен, но сначала печатает, сколько раз были отправлены SIGUSR1 и SIGUSR2.
Пожалуйста, обратите внимание, что это проблема из класса, поэтому она не предназначена для использования, просто чтобы проверить нас. Кроме того, никакие другие сигналы, кроме упомянутых трех, не будут отправлены.
Вот что я получил:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
int sigUsr1Count = 0;
int sigUsr2Count = 0;
static void sighandler(int signum){
switch(signum){
case SIGUSR1:
sigUsr1Count++;
break;
case SIGUSR2:
sigUsr2Count++;
break;
case SIGTERM:
printf("%d %d\n", sigUsr1Count, sigUsr2Count);
exit(0);
}
}
int main(int argc, char ** argv){
pid_t mypid = getpid();
fprintf(stderr, "My PID is %d\n", mypid);
struct sigaction sa;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sa.sa_handler = sighandler;
iAssert(-1 != sigaction(SIGUSR1, &sa, NULL), "sigaction1 failed");
iAssert(-1 != sigaction(SIGUSR2, &sa, NULL), "sigaction1 failed");
iAssert(-1 != sigaction(SIGTERM, &sa, NULL), "sigaction1 failed");
while(true){
fprintf(stderr, "Waiting...\n");
sleep(3);
}
return 0;
}
Я где-то читал на форуме, что при использовании sigaction
обработчики сигналов НЕ сбрасываются в значения по умолчанию, если в поле sa_flags
не установлено значение SA_RESETHAND
. Тем не менее, это не так со мной. (Страница man описывает флаг SA_RESETHAND
, но не содержит явных сведений о действии в ситуации, когда он опущен.)
Когда я запускаю программу, она переходит к моим обработчикам только при первой отправке SIGUSR1 или SIGUSR2, после чего программа завершает работу с сообщением:
User defined signal 1 (or 2)
В этом смысле программа выводит правильные значения только в том случае, если либо: SIGUSR1 и SIGUSR2 не были отправлены вообще, либо каждое из них было отправлено не более одного раза.
Макрос и функция iAssert
:
#define iAssert(cond, msg) crash(cond, msg, __LINE__)
void crash(bool cond, char * msg, int line){
if(!cond){
perror(msg);
fprintf(stderr, "at line %d\n", line);
exit(EXIT_FAILURE);
}
}
Методы компиляции, которые я уже пробовал (одинаковые с каждым из них):
gcc 1.c
gcc -std=c99 1.c
gcc -std=c11 1.c
Есть идеи?
Спасибо.