您的位置:首页 > 运维架构 > Linux

关于linux线程实时信号的一个问题

2007-07-02 09:18 411 查看
关于linux线程实时信号的一个问题

最近在项目的迁移方面发现linux线程的一个问题 感觉很奇怪,在2.4内核运行正常的程序在高版本linux上运行出现实时信号错误,Real-Time 0.原来是,在启动network线程的时候,用的事信号驱动I/O。在这个线程启动的时候,会把SIGRTMIN和SIGIO, 信号block,然后在 wait 这信号,如果条件满足会向自己发一个SIGRTMIN信号,sigqueue(getpid(),SIGRTMIN,sigval).问题就出在getpid()上,原来在rh8的内核上,每个线程都有一个pid,和进程的pid不一样。所以用这个语句发送的信号在rh8上事正常work的 。
但是到了高版本的linux,一个进程的所有线程gepid()都是唯一的。这时候用这个语句发送 信号等于是向进程发信号,但是进程的信号掩码没有把这个信号block,所以整个程序会推出。
下面是一个测试代码,在centos和rh8 run,结果完全不一样。
#include<errno.h>
#include <signal.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/types.h>

enum {MYSELF, FromMain};

void TimerTick(int time)
{
printf("TimerTick,send a signal to pid=%d/n",getpid());
union sigval svNew;
svNew.sival_int = MYSELF;
sigqueue(getpid(), SIGRTMIN, svNew);
};

void * pthread_routine(void * arg)
{

sigset_t m_Sigset;
sigemptyset(&m_Sigset);
sigaddset(&m_Sigset, SIGRTMIN);
sigprocmask(SIG_BLOCK, &m_Sigset, NULL);
printf("I am routine ,pid=",getpid());
printf("waiting for%d/n",SIGRTMIN);

signal(SIGALRM, TimerTick);

struct itimerval itvInterval;
itvInterval.it_value.tv_sec = 1;
itvInterval.it_value.tv_usec = 100;
itvInterval.it_interval.tv_sec = 1;
itvInterval.it_interval.tv_usec = 60 * 1000;
setitimer(ITIMER_REAL, &itvInterval, NULL);
while(1){

siginfo_t siginfo;
int sigRet;
sigRet = sigwaitinfo(&m_Sigset, &siginfo);
//printf("Got a signal %d/n",sigRet);
if (sigRet == -1 || sigRet == SIGIO) {
if (sigRet == -1 && errno == EINTR)
continue;
else {
printf("Error/n");
}
}
if(siginfo.si_value.sival_int==MYSELF)
{
printf("Got a signal from myself,the signum is %d/n",sigRet);
}else if(siginfo.si_value.sival_int==FromMain)
{
printf("Got a signal from main thread ,the signu is %d/n",sigRet);
}
else{
printf("Got a signal from unkown/n");
}
}
return NULL;
};

int main()
{
sigset_t mainset;
sigset_t testset;
sigemptyset(&testset);
printf("I am main pid=/n",getpid());
pthread_t thread_id;
size_t stack_size;
pthread_create(&thread_id,NULL,pthread_routine,NULL);
printf("selep some time in main thread/n");
sleep(5);
sigprocmask(SIG_BLOCK, &testset, &mainset);
if(sigismember(&mainset,SIGRTMIN))
{
printf("the SIGRTMIN is in the mainset,it's set by other thread/n");
}
else{
printf("the SIGRTMIN is no the mainset/n");
}
sigprocmask(SIG_BLOCK,&mainset,NULL);

printf("the pid is %d/n",getpid());
union sigval svNew;
svNew.sival_int = FromMain;
sigqueue(getpid(), SIGRTMIN, svNew);
pthread_join(thread_id,NULL);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: