2011-04-21 21 views
2

我有一个程序,我调用一个信号sigkill(getpid(), SIGUSR1)。我希望信号来的时候,而不是信号处理程序的线程函数应该被调用,或两者。 为此我填入了sigev_notifySIGEV_THREAD为什么线程函数不能调用? (SIGEV_THREAD)

但不幸的是,线程函数没有被调用。为什么这样?

这里是代码如下:

#include <stdlib.h> 
#include <time.h> 
#include <stdio.h> 
#include <signal.h> 
#include <errno.h> 
#include <string.h> 

static void ThreadhandlerTimer1(int); 
void sig_handlerTimer1(int); 

static void threadFunction(union sigval sv) // Should be invoked on receipt of signal "SIGEV_THREAD" 
{ 
    printf("Thread function invoked"); 
} 

int main() 
{ 
    int i; 
    static struct sigaction sa; 
    static struct sigevent sevp; 

    memset (&sevp, 0, sizeof (struct sigevent)); 
    sevp.sigev_value.sival_ptr = NULL; 
    sevp.sigev_notify = SIGEV_THREAD; 
    sevp.sigev_notify_attributes = NULL; 
    sevp.sigev_signo = SIGUSR1; 
    sevp.sigev_notify_function=threadFunction; 

    /* Setting the signal handlers */ 

    sa.sa_handler = sig_handlerTimer1; 
    sa.sa_flags = 0; 
    sigaction(SIGUSR1, &sa, NULL); 

    for(i=0; i<10; i++) 
    { 
      if((i==3) || (i==6)){ 
       kill(getpid(), SIGUSR1); 
      } 

      printf("%d\n",i); 
      sleep(1); 
    } 
    } 

    void sig_handlerTimer1(int signum) 
    { 
     printf("Caught signal: %d\n",signum); 
    } 
+1

它怎么会工作?你没有把任何东西传递给sevp。 – 2011-04-21 14:00:18

+0

另外,一般而言,混合线程和信号是一个非常糟糕的想法。 – 2011-04-21 14:00:58

+0

@Sami:您的意见“混合线程和信号非常糟糕”表明您可能从未使用过POSIX计时器。 – kingsmasher1 2011-04-22 15:13:40

回答

2

根据this documentation,所述sigevent结构仅由“一些信号生成功能,例如高分辨率计时器期满时,异步I/O完成,进程间支持消息到达以及sigqueue()函数。“

我不知道你对这段代码的真正计划是什么(也许你可以告诉我们),但实际上,你直接提高了信号,这可能不是使用SIGEV支持的情况之一。如果此代码与您在生产中想要的相近,则可以简单地拨打sigqueue()而不是kill(),它可能正常工作。

+0

让我试试看。 – kingsmasher1 2011-04-21 13:22:18

+0

但为什么只有sigqueue? – kingsmasher1 2011-04-21 13:31:05

+0

对不起,这不行。即使使用sigqueue也不会调用我的线程函数。 – kingsmasher1 2011-04-21 13:32:56

0

从你的代码看来,你刚刚为sigevent赋值,而不是在代码中使用任何地方。

static struct sigevent sevp;

memset (&sevp, 0, sizeof (struct sigevent)); 
sevp.sigev_value.sival_ptr = NULL; 
sevp.sigev_notify = SIGEV_THREAD; 
sevp.sigev_notify_attributes = NULL; 
sevp.sigev_signo = SIGUSR1; 
sevp.sigev_notify_function=threadFunction; 

要调用threadFunction,从信号处理程序调用此。

> void sig_handlerTimer1(int signum) 
> { 
> printf("Caught signal: %d\n",signum); 
> threadFunction(signum); 
> } 

如果你想使用SEVP,使用像timer_create()和timer_settime()。 查看该链接: http://ptgmedia.pearsoncmg.com/images/0201633922/sourcecode/sigev_thread.c

+2

从信号处理程序中调用'threadFunction'几乎肯定是错误的。 – 2011-04-21 18:57:59

+0

ahhhh,那么为什么不在主体中调用线程函数,如果我想调用它呢?对?你知道什么是线程函数吗?或者线程函数的重要性是什么?你真的需要清除一些基本的基本概念。 – kingsmasher1 2011-04-22 06:30:02

+0

@ kingmasher1:从信号处理程序中调用几乎任何东西都会遇到麻烦。例如,参见https://www.securecoding.cert.org/confluence/display/seccode/SIG30-C.+Call+only+asynchronous-safe+functions+within+signal+handlers。 – 2011-04-22 22:57:49

相关问题