UNIX/Linux信号处理:SIGEV_THREAD
我在代码中放置了一个简单的信号处理程序。我已经初始化sigevent结构,并使用处理函数来捕捉信号。UNIX/Linux信号处理:SIGEV_THREAD
有人可以请指出为什么代码不工作?理想情况下,如果有信号,我的处理程序应该被调用。但事实并非如此。
请帮助我, 感谢 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 sigaction
和sigaction()
是如何做到这一点的。相反,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()
来阻止每个其他线程中的信号。
我觉得你在这里混淆了你的信号处理成语,为您营造的sigevent结构,然后什么也不做它,然后将信号中使用的信号()处理程序。以下代码显示了基于您的代码的非常简单的信号处理例程;注意我已经改变了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");
}
但是,OP对'sigevent' **没有做任何事情**在逻辑上必须是问题,所以+1。 – 2011-03-01 11:54:06
这是我知道的方法,但我想使用sigevent并使用SIGEV_THREAD来调用该函数。如果你能以这种方式帮助我,那将会很棒 – kingsmasher1 2011-03-01 12:16:00
通过简单的拖网通过文档,你所得到的问题是,sigevent是关于事件处理而不是信号处理。这听起来像你想在你的进程接收到SIGRTMIN信号时在新线程中调用信号处理程序,而sigevent用于async io(请参阅aio手册页)。您需要查看signal()的文档,并且您的操作系统是否支持sigaction()以查看您可以执行的操作。 – Jackson 2011-03-01 15:30:40