[英]Linux and real-time signals
I am trying to write simple program that uses real-time signals in Linux. 我正在尝试编写在Linux中使用实时信号的简单程序。 But I encountered strange behaviour, first the code:
但是我遇到了奇怪的行为,首先是代码:
#include<signal.h>
#include<sys/types.h>
#include<stdlib.h>
#include<stdio.h>
#include"errhandling.h"
#include<string.h>
#include<errno.h>
#include<unistd.h>
void baz(int sig,siginfo_t* info,void *context)
{
if (sig==SIGUSR1)
printf("SIGUSR1 %d\n",info->si_value.sival_int);
else if(sig==SIGRTMIN)
printf("SIGRTMIN %d\n",info->si_value.sival_int);
else
printf("SIGRTMIN+1 %d\n",info->si_value.sival_int);
return ;
}
void sig_output()
{
sigset_t set;
sigprocmask(0,NULL,&set);
printf("blokowane sa: ");
if (sigismember(&set,SIGUSR1))
printf("SIGUSR1 ");
if(sigismember(&set,SIGUSR2))
printf(" SIGUSR2");
printf("\n");
return ;
}
int received=0;
int usr2=0;
void foo(int sig)
{
return ;
}
void usr1_handler(int sig)
{
printf("usr1_handler\n");
//++received;
}
void usr2_handler(int sig)
{
usr2=1;
}
int main(int argc,char **argv)
{
int i=0;
pid_t pid=getppid();
struct sigaction a;
struct sigaction a2;
a.sa_flags=SA_SIGINFO;
sigset_t set;
sigemptyset(&set);
//sigaddset(&set,SIGRTMAX);
sigemptyset(&(a.sa_mask));
sigemptyset(&(a2.sa_mask));
a.sa_sigaction=baz;
sigaction(SIGRTMIN,&a,NULL);
a2.sa_handler=usr1_handler;
sigaction(SIGRTMIN+1,&a2,NULL);
//sigprocmask(SIG_SET,&(a.sa_mask),NULL);
while(!usr2)
{
printf("while\n");
sigsuspend(&set);
}
//pause()
printf("after while\n");
return EXIT_SUCCESS;
}
when I run this program and it enters this loop with sigsuspend and I send to this program SIGRTMIN everything goes ok - handler executes and it waits for another signal, but when I send it SIGRTMIN+1 I get segmentation fault. 当我运行该程序时,它以sigsuspend进入此循环,并向该程序发送SIGRTMIN一切正常-处理程序执行并等待另一个信号,但是当我发送SIGRTMIN + 1时,出现分段错误。
It seems that for real-time signals I need to use this extended handler with 3 arguments, but why? 似乎对于实时信号,我需要使用带有3个参数的扩展处理程序,但是为什么呢? Is it specified somewhere?
是否在某处指定? I run this program on my friend OpenSUSE 12.1 and I don't get segmentation fault for SIGRTMIN+1, but on my Xubuntu 11.10, when I send SIGRTMIN+1 I am getting segmentation fault.
我在朋友OpenSUSE 12.1上运行了该程序,但没有遇到SIGRTMIN + 1的分段错误,但是在我的Xubuntu 11.10上,当我发送SIGRTMIN + 1时出现了分段错误。 Is it problem with my system?
我的系统有问题吗? Or is it implementation dependent?
还是依赖于实现?
It seems you are missing to assign a handler to a2.sa_sigaction
. 似乎您缺少为
a2.sa_sigaction
分配处理程序。
In general it is not good idea to refer to signals by a raw integer values, as the definition for the various signals might be platform specific. 通常,用原始整数值引用信号不是一个好主意,因为各种信号的定义可能是特定于平台的。
Update:
Make sure the struct sigaction
structures are initialised properly by for example memset()
ing them to 0. Update:
确保struct sigaction
结构已正确初始化,例如通过memset()
它们设置为0。
Don't use printf() and friends from inside a signal handler. 不要在信号处理程序内部使用printf()和朋友。 Don't be stubborn... Here's a substitute.
不要固执...这是一个替代品。
#include <stdarg.h>
int myprintf(const char *fmt, ...);
int myprintf(const char *fmt, ...)
{
va_list args;
char buff[512];
int rc;
va_start( args, fmt );
rc = vsnprintf ( buff, sizeof buff, fmt, args );
va_end (args);
if (rc >0 && rc < sizeof buff) write(1, buff, rc);
return rc;
}
UPDATE: this appears to work: 更新:这似乎起作用:
#include <signal.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#pragma #include"errhandling.h"
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdarg.h>
int myprintf(const char *fmt, ...);
int myprintf(const char *fmt, ...)
{
va_list args;
char buff[512];
int rc;
va_start( args, fmt );
rc = vsnprintf ( buff, sizeof buff, fmt, args );
va_end (args);
if (rc > 0 && rc < sizeof buff) write(1, buff, rc);
return rc;
}
void baz(int sig, siginfo_t *info, void *context)
{
#define INFO_VAL(p) p?p->si_value.sival_int:0
if (sig==SIGUSR1)
myprintf("SIGUSR1 %d\n", INFO_VAL(info) );
else if(sig==SIGRTMIN)
myprintf("SIGRTMIN %d\n", INFO_VAL(info) );
else
myprintf("SIGRTMIN%+d %p\n", sig-SIGRTMIN, INFO_VAL(info) );
return ;
#undef INFO_VAL
}
void sig_output()
{
sigset_t set;
sigprocmask(0,NULL,&set);
myprintf("blokowane sa: ");
if (sigismember(&set,SIGUSR1))
myprintf("SIGUSR1 ");
if(sigismember(&set,SIGUSR2))
myprintf(" SIGUSR2");
myprintf("\n");
return ;
}
volatile int received=0;
volatile int usr2=0;
void foo(int sig)
{
return ;
}
void usr1_handler(int sig)
{
myprintf("usr1_handler\n");
//++received;
}
void usr2_handler(int sig)
{
usr2=1;
}
int main(int argc,char **argv)
{
int i=0;
pid_t pid=getppid();
struct sigaction a, a2;
sigset_t set;
sigemptyset(&set);
//sigaddset(&set,SIGRTMAX);
sigemptyset(&a.sa_mask);
sigemptyset(&a2.sa_mask);
a.sa_flags = 0;
a2.sa_flags = SA_SIGINFO;
a2.sa_sigaction = baz;
a.sa_handler = usr1_handler;
sigaction(SIGUSR1,&a,NULL);
a.sa_handler = usr2_handler;
sigaction(SIGUSR2,&a,NULL);
sigaction(SIGRTMIN+1,&a2,NULL);
sigaction(SIGRTMIN+2,&a2,NULL);
sigaction(SIGRTMIN+3,&a2,NULL);
//sigprocmask(SIG_SET,&(a.sa_mask),NULL);
while(!usr2)
{
myprintf("while(!usr2)\n");
sigsuspend(&set);
}
//pause()
myprintf("after while\n");
return EXIT_SUCCESS;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.