이 프로그램은 실시간 신호를 자신에게 보내고 처리합니다. 처리가 완료되면 수신 한 신호를 수신 한 순서대로 출력합니다.
$ cat realtime.c
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int received_signals[10];
int received_signals_value[10];
int received_signals_count = 0;
void real_time_handler(int sig_number, siginfo_t * info,
void * arg __attribute__ ((unused)))
{
received_signals[received_signals_count] = sig_number - SIGRTMIN;
received_signals_value[received_signals_count] = info->si_value.sival_int;
++received_signals_count;
}
void send_real_time_signal(int sig_number, int value)
{
union sigval sig_value;
printf("Sending signal SIRTMIN+%d, value %d\n", sig_number, value);
sig_value.sival_int = value;
if (sigqueue(getpid(), sig_number + SIGRTMIN, sig_value) < 0) {
perror("sigqueue");
exit(EXIT_FAILURE);
}
}
int main()
{
struct sigaction action;
sigset_t set;
int i;
// Handler setup
action.sa_sigaction = real_time_handler;
sigemptyset(&action.sa_mask);
action.sa_flags = SA_SIGINFO;
if ((sigaction(SIGRTMIN + 1, & action, NULL) < 0)
|| (sigaction(SIGRTMIN + 2, & action, NULL) < 0)
|| (sigaction(SIGRTMIN + 3, & action, NULL) < 0)) {
perror("sigaction");
exit(EXIT_FAILURE);
}
// Block all signals
sigfillset(&set);
sigprocmask(SIG_BLOCK, &set, NULL);
send_real_time_signal(1, 0);
send_real_time_signal(2, 1);
send_real_time_signal(3, 2);
send_real_time_signal(1, 3);
send_real_time_signal(2, 4);
send_real_time_signal(3, 5);
send_real_time_signal(3, 6);
send_real_time_signal(2, 7);
send_real_time_signal(1, 8);
send_real_time_signal(3, 9);
// Unblock all signals
sigfillset(&set);
sigprocmask(SIG_UNBLOCK, &set, NULL);
// To make sure we're handling all signals before resuming
sleep(1);
// Display results
for (i = 0; i < received_signals_count; ++i) {
printf("Received signal SIGRTMIN+%d, value %d\n",
received_signals[i], received_signals_value[i]);
}
return EXIT_SUCCESS;
}
나는 일관되게 아래 출력을 얻습니다.
$ gcc -Wall -Wextra -O2 -o realtime realtime.c
$ ./realtime
Sending signal SIRTMIN+1, value 0
Sending signal SIRTMIN+2, value 1
Sending signal SIRTMIN+3, value 2
Sending signal SIRTMIN+1, value 3
Sending signal SIRTMIN+2, value 4
Sending signal SIRTMIN+3, value 5
Sending signal SIRTMIN+3, value 6
Sending signal SIRTMIN+2, value 7
Sending signal SIRTMIN+1, value 8
Sending signal SIRTMIN+3, value 9
Received signal SIGRTMIN+3, value 2
Received signal SIGRTMIN+3, value 5
Received signal SIGRTMIN+3, value 6
Received signal SIGRTMIN+3, value 9
Received signal SIGRTMIN+2, value 1
Received signal SIGRTMIN+2, value 4
Received signal SIGRTMIN+2, value 7
Received signal SIGRTMIN+1, value 0
Received signal SIGRTMIN+1, value 3
Received signal SIGRTMIN+1, value 8
signal (7) ( http://man7.org/linux/man-pages/man7/signal.7.html )에 쓰여진 내용과 모순됩니다 .
실시간 신호는 보장 된 순서로 전달됩니다. 동일한 유형의 여러 실시간 신호가 전송 된 순서대로 전달됩니다. 다른 실시간 신호가 프로세스로 전송되면 가장 낮은 번호의 신호부터 전달됩니다. (즉, 낮은 번호의 신호가 가장 높은 우선 순위를 갖습니다.) 반면에 프로세스에 대해 여러 표준 신호가 보류중인 경우 전달되는 순서가 지정되지 않습니다.
내가 이해하는 한 다음을 받아야합니다.
$ ./realtime
Sending signal SIRTMIN+1, value 0
Sending signal SIRTMIN+2, value 1
Sending signal SIRTMIN+3, value 2
Sending signal SIRTMIN+1, value 3
Sending signal SIRTMIN+2, value 4
Sending signal SIRTMIN+3, value 5
Sending signal SIRTMIN+3, value 6
Sending signal SIRTMIN+2, value 7
Sending signal SIRTMIN+1, value 8
Sending signal SIRTMIN+3, value 9
Received signal SIGRTMIN+1, value 0
Received signal SIGRTMIN+1, value 3
Received signal SIGRTMIN+1, value 8
Received signal SIGRTMIN+2, value 1
Received signal SIGRTMIN+2, value 4
Received signal SIGRTMIN+2, value 7
Received signal SIGRTMIN+3, value 2
Received signal SIGRTMIN+3, value 5
Received signal SIGRTMIN+3, value 6
Received signal SIGRTMIN+3, value 9
Linux 커널 소스 코드를 빠르게 살펴 보았지만 실시간 신호가 처리되는 곳을 (아직) 찾을 수 없었습니다.
내가 뭔가 잘못했거나 빠졌거나 매뉴얼 페이지가 부정확합니까?
문제는 다른 신호가 실행중인 신호 처리기를 중단하도록 허용한다는 것입니다.
sigemptyset(&action.sa_mask);
이 sa_mask
필드는이 핸들러의 실행을 중단 할 수없는 신호 집합을 지정합니다.
이것은 SIGRTMIN + 1
당신이 그것에 대해 무엇이든 할 수 있기 전에 당신 이 처리하기 시작하는 다른 더 낮은 우선 순위 신호 를 얻는다는 것을 의미합니다 . 그 신호는 차례로 또 다른 신호에 의해 중단됩니다.
이 문제를 해결하려면 다른 신호가 핸들러를 방해하지 않도록합니다.
sigfillset(&action.sa_mask);
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다