UNIX/Linux 信号处理:SIGEV_THREAD

发布于 2024-10-20 00:32:19 字数 674 浏览 3 评论 0原文

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

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

请帮我, 谢谢 粉碎王1

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
}

I have put a simple signal handler in my code. I have initialised the sigevent structure, with a handler function to catch the signal.

Can someone please pin-point as to why the code is not working? Ideally if there is a signal, my handler should be called. But it is not.

Please help me,
Thanks
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
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

弃爱 2024-10-27 00:32:19

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() 来阻止所有其他线程中的信号。

struct sigevent is not about specifying how the process will handle a signal - struct sigaction and sigaction() are how you do that. Instead, struct sigevent is used to specify how your process will be informed of some asychronous event - like the completion of asychronous IO, or a timer expiring.

The sigev_notify field specifies how the event should be notified:

  • SIGEV_NONE - no notification at all. The remainder of the fields are ignored.
  • SIGEV_SIGNAL - a signal is sent to the process. The sigev_signo field specifies the signal, the sigev_value field contains supplementary data that is passed to the signal handling function, and the remainder of the fields are ignored.
  • SIGEV_THREAD - a function is called in a new thread. The sigev_notify_function field specifies the function that is called, sigev_value contains supplementary data that is passed to the function, and sigev_notify_attributes specifies thread attributes to use for the thread creation. The remainder of the fields are ignored.

Note in particular that if you set SIGEV_THREAD, the sigev_signo field is ignored - the struct sigevent is about specifying either a thread or a signal as a notification method, not about specifying a thread as the way that a signal should be handled.

The struct sigevent must also be passed to a function - like timer_create() - that sets up the asychronous event that will be notified. Simply creating a struct sigevent object does not do anything special.

If you wish to use a dedicated thread to handle a signal, create the thread up front and have it loop around, blocking on sigwaitinfo(). Use sigprocmask() to block the signal in every other thread.

短暂陪伴 2024-10-27 00:32:19

我认为您在这里混淆了信号处理习惯用法,您创建了一个 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 机器)。

I think you are mixing up your signal handling idioms here, you create a sigevent structure and then do nothing with it and then use signal() within the signal handler. The following code shows a very simple signal handling routine based on your code; note that I have changed the definition of my_handler. If you need more sophisticated handling then sigaction() is probably the system call you need to look into.

#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!
}

This works under cygwin on my windows box (no access to a linux box at the minute).

我的鱼塘能养鲲 2024-10-27 00:32:19

我希望这能起作用。

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

I hope this works.

#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");
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文