사용자에게 신호 번호를 입력하도록 요청한 다음 처리기를 호출하는 프로그램을 작성하려고 합니다.
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void decide(int signo)
{
printf("I received signal\n");
}
int main()
{
int signum;
printf("Enter Signal Number:");
scanf("%d", &signum);
if(signal(signum,decide) == SIG_ERR)
{
perror("signal");
}
//pause();
printf("I hope you have a good evening!\n");
return 0;
}
그러나 신호 처리기를 건너뛰고 항상 마지막 줄을 인쇄하는 것 같습니다. 핸들러를 호출하도록 무엇을 변경할 수 있습니까?
답변1
이것signal
기능(아마도 이름과 달리) 신호 처리 동작만 설정합니다.미래나타나는 신호:
이
signal()
기능은 신호 번호를 수신하는 세 가지 방법 중 하나를 선택합니다.신호 추후 처리 예정. 값이 있는 경우기능SIG_DFL인 경우 기본적으로 신호를 처리해야 합니다. 값이 있는 경우기능SIG_IGN의 경우 이 신호는 무시됩니다. 그렇지 않은 경우 애플리케이션은 다음을 보장해야 합니다.기능이 신호가 발생할 때 호출될 함수에 대한 포인터입니다.
귀하의 프로그램은 신호 처리기를 설정하고 오류가 없는지 확인합니다. 훌륭합니다! - 그러나 계속해서 작별 인사를 인쇄하고 즉시 종료합니다. 이 시점에서 전체 프로세스(신호 처리기 포함)는 더 이상 존재하지 않습니다.
환경신호 처리기는 Unix 모델에서 별개의 이벤트입니다.접수 및 처리신호. 핸들러가 설정되면 앞으로 도착하는 모든 신호는 처리를 위해 핸들러로 전송되며 프로그램의 나머지 부분은 계속 실행됩니다. 일치하는 신호가 발생하지 않으면 핸들러는 조용히 앉아서 아무 것도 할 필요가 없습니다.
거기예신호가 종료되기 전에 신호를 전달할 수 있는 아주 작은 창입니다. 이 창은 본질적으로 귀하의 위치입니다pause()
부르다주석 처리됨 - 사실 거의 그 정도입니다이 기능의 목적 pause
은:
이
pause()
함수는 신호가 전달될 때까지 호출 스레드를 일시 중단해야 하며, 이 작업은 신호 포착 함수를 실행하거나 프로세스를 종료하는 것입니다.
그렇지 않으면 마이크로 창 이든 마이크로 창이든 다른 터미널에서 핸들러를 실행할 pause
수 있습니다 . kill -XYZ $pid
제가 이 작업을 수행하는 세션은 다음과 같습니다.
mwh:/tmp$ ./test
Enter Signal Number:12
I received signal
I hope you have a good evening!
mwh:/tmp$
test
다른 터미널에서 프로세스의 PID를 찾아 ps awx
실행했습니다 kill -12 9245
. 프로세스는 Enter를 누를 때까지 아무것도 하지 않고 그대로 있습니다 kill
. 신호 처리기를 실행하면 메시지가 인쇄되고 반환되며 나머지 프로그램이 실행되어 완료됩니다.test
pause()
프로세스가 신호를 보내길 원하는 경우나에게어떤 이유로든 당신도 이것을 할 수 있습니다. 이것raise
기능이것은 당신이 하기 위해 태어난 것입니다:
이
raise()
함수는 신호를 보내야합니다신호실행 중인 스레드나 프로세스에. 신호 처리기가 호출되면 raise() 함수는 신호 처리기가 반환될 때까지 반환되어서는 안 됩니다.
그래서
raise(signum);
대체가 pause();
작동합니다.
흥미로운 결과를 얻을 수 있는 SIGKILL 또는 기타 포착할 수 없는 신호의 특수한 경우를 제외하고는 여기서는 그다지 유용하지 않습니다(9와 19를 입력해 보십시오!). 그러나 신호 및 프로세스 모델이 작동하는 방식을 탐색하는 경우 PID를 찾는 데 드는 시간과 노력을 절약할 수 있습니다.
당신은 또한 수사용kill(getpid(), signum);
또는 pthread_kill(pthread_self(), sig);
(정확히 로 정의됨 raise(signum)
).