UNIX / Linux信号处理:SIGEV_THREAD

时间:2011-03-01 11:37:55

标签: c linux unix posix signals

我在代码中放了一个简单的信号处理程序。我初始化了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
}

3 个答案:

答案 0 :(得分:14)

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_notify_attributes指定用于创建线程的线程属性。其余字段将被忽略。

请特别注意,如果您设置SIGEV_THREAD,则会忽略sigev_signo字段 - struct sigevent是指线程或信号指定为通知方法,而不是将线程指定为应该处理信号的方式。

还必须将struct sigevent传递给函数 - 如timer_create() - 设置将通知的异步事件。简单地创建一个struct sigevent对象并没有什么特别之处。

如果您希望使用专用线程来处理信号,请在前面创建线程并使其循环,在sigwaitinfo()上阻塞。使用sigprocmask()来阻止每个其他线程中的信号。

答案 1 :(得分:2)

我认为你在这里混淆了你的信号处理习语,你创建了一个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!
}

这可以在我的Windows框中cygwin下工作(一分钟都无法访问linux框)。

答案 2 :(得分:0)

我希望这有效。

#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");
}