UNIX / Linux信号处理:SIGEV_THREAD

我在我的代码中放置了一个简单的信号处理程序。 我已经初始化sigevent结构,用一个处理函数来捕捉信号。

有人可以指出为什么代码不工作? 理想情况下,如果有信号,我的处理程序应该被调用。 但事实并非如此。

请帮助我,谢谢Kingsmasher1

enter code here #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <signal.h> #include <time.h> void my_handler(int sival_int, void* sival_ptr) { printf("my_handler caught\n"); signal(sig,my_handler); } int main() { struct sigevent sevp; sevp.sigev_notify=SIGEV_THREAD; sevp.sigev_signo=SIGRTMIN; sevp.sigev_value.sival_ptr=NULL; sevp.sigev_notify_function=(void*)my_handler; kill(0,SIGRTMIN); // This should invoke the signal and call the function } 

struct sigevent不是指定进程如何处理信号 – struct sigactionsigaction()是你如何做的。 相反, struct sigevent用于指定如何通知某个异步事件的进程,如异步IO的完成或计时器到期。

sigev_notify字段指定如何通知事件:

  • SIGEV_NONE – 根本没有通知。 其余的字段被忽略。
  • SIGEV_SIGNAL – 一个信号被发送到进程。 sigev_signo字段指定信号, sigev_value字段包含传递给信号处理函数的补充数据,其余字段将被忽略。
  • SIGEV_THREAD – 在新线程中调用一个函数。 sigev_notify_function字段指定被调用的函数, sigev_value包含传递给函数的补充数据, sigev_value指定用于线程创建的线程属性。 其余的字段被忽略。

尤其要注意的是,如果设置了SIGEV_THREAD ,则sigev_signo字段将被忽略 – struct sigevent是指定线程或信号作为通知方法,而不是指定线程作为信号处理的方式。

struct sigevent也必须被传递给一个函数,比如timer_create() ,它设置了将被通知的异步事件。 简单地创建一个struct sigevent对象不会做任何特殊的事情。

如果您希望使用专用线程来处理信号,请首先创建线程,然后循环,在sigwaitinfo()sigwaitinfo()阻塞。 使用sigprocmask()在每个其他线程中阻塞信号。

我认为你在这里混合你的信号处理习惯用法,你创建一个sigevent结构,然后不做任何事情,然后在信号处理程序中使用signal()。 以下代码根据您的代码显示了一个非常简单的信号处理例程; 注意我已经改变了my_handler的定义。 如果你需要更复杂的处理,然后sigaction(),如果系统调用你需要看看。

 #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <signal.h> #include <time.h> void my_handler(int sig) { printf("my_handler caught\n"); signal(sig,my_handler); } int main() { signal(SIGRTMIN,my_handler); kill(0,SIGRTMIN); // This should invoke the signal and call the function while(1) ; // Infinite loop in case the program ends before the signal gets caught! } int main() { signal(SIGRTMIN,my_handler); kill(0,SIGRTMIN); // This should invoke the signal and call the function while(1) ; // Infinite loop in case the program ends before the signal gets caught! } 

这在我的Windows系统下的cygwin下工作(在一分钟内不能访问linux系统)。

我希望这个工程。

 #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <signal.h> #include <time.h> void my_handler (int sig) { printf ("my_handler caught\n"); signal (sig, my_handler); } int main () { int signo; struct sigevent sevp; sigset_t set; if (sigemptyset (&set) == -1) perror ("sigemptyset"); if (sigaddset (&set, SIGRTMIN) == -1) perror ("sigaddset"); if (sigprocmask (SIG_BLOCK, &set, NULL) == -1) perror ("sigprocmask"); sevp.sigev_notify = SIGEV_THREAD; sevp.sigev_signo = SIGRTMIN; sevp.sigev_value.sival_ptr = NULL; kill (0, SIGRTMIN); if (sigwait (&set, &signo) == 0) my_handler (signo); else perror ("sigwait"); }