风言枫语  

信号导致的问题

不是任何信号我们都需要的,如果遇到我们不想处理的信号,我们怎么避免这个信号?

 

1.      信号屏蔽

    intsigprocmask(int how,//操作方式

                                                               SIG_BLOCK屏蔽信号

                                                               SIG_UNBLOCK剪除屏蔽信号

                                                               SIG_SETMASK修改屏蔽信号

                                   constsigset_t *sigs,//操作的信号集合

                                   sigset_t*oldsigs);//返回原来操作的信号集合

返回值:执行成功返回0,失败返回-1。

屏蔽信号的步骤:

1.      声明信号集

        sigset_t sigs;

2.      加入屏蔽信号

        一组信号集合维护函数

        2.1. 清空集合sigemptyset

               int sigemptyset( sigset_t *set);

            2.2. 添加信号到集合sigaddset

                int sigaddset( sigset_t *set ,int  signum);

            2.3. 从集合删除信号sigdelset

                int sigdelset(sigset_t *set,int signum);

            2.4. 添加所有信号到集合sigfillset

                 int sigfillset( sigset_t*set);

2.5.  判定信号是否在集合sigismember

         int sigismember(const sigset_t *set ,int signum);

3.      屏蔽信号

4.      接触屏蔽

 

例子:

 

#include<stdio.h>

#include<signal.h>

 

 

void main()

{

int sum=0;

//声明信号集

sigset_t sigs;

//清空信号集

sigemptyset(&sigs);

//添加信号到信号集

sigaddset(&sigs,SIGINT); //

//屏蔽信号

sigprocmask( SIG_BLOCK,&sigs,0);

for(i=1;i<=10;i++)

{

     sum+=i;

     sleep(1);

}

printf(“sum=%d\n”,sum);

//捡出屏蔽

sigprocmask(SIG_UNBLOCK,&sigs,0);//捡出屏蔽,信号立即触犯,打印over不能//执行,如果没有捡出屏蔽信号,over正常打印

printf(“OVER!\n”);

}

 

说明:当屏蔽了某个信号,这个信号将不会触发,直到我们捡出了该信号,信号才会触发。

 

2.查询被屏蔽的信号

                                 intsigpending(sigset_t *sets); 返回0成功,-1失败

例子:

 

#include<stdio.h>

#include<signal.h>

 

 

void main()

{

int sum=0;

//声明信号集

sigset_t sigs;

sigset_t sigp;

//清空信号集

sigemptyset(&sigs);

//添加信号到信号集

sigaddset(&sigs,SIGINT); //

//屏蔽信号

sigprocmask( SIG_BLOCK,&sigs,0);

for(i=1;i<=10;i++)

{

     sum+=i;

     sigpending(&sigp);//得到屏蔽的信号

     if(sigismemeber(&sigp,SIGINT))

     {

           printf(“信号SIGINT在排队\n”);

     }

     sleep(1);

}

printf(“sum=%d\n”,sum);

//捡出屏蔽

sigprocmask(SIG_UNBLOCK,&sigs,0);

printf(“OVER!\n”);

}

 

 

 

 

2.      信号屏蔽的切换

    int sigsuspend(sigset_t *sigs);

                                   屏蔽新的信号,原来的信号失效.

                                   sigsuspend是阻塞函数.对参数信号屏蔽.

                                   对参数没有指定的信号不屏蔽,但当没有屏蔽信号处理函数调用完毕

                                   sigsuspend返回条件:

                                                        1.信号发生,并且信号是非屏蔽信号

                                                        2.信号必须要处理,而且处理函数返回后,sigsuspend才返回.

                                  

                                   sigsuspend设置新的屏蔽信号,保存旧的屏蔽信号

                                   而且当sigsuspend返回的时候,恢复旧的屏蔽信号.

 

函数sigsuspend将进程的信号屏蔽码设置为sigs,然后与pause()函数一样等待信号的发生并执行完信号处理函数。信号处理函数执行完后再把进程的信号屏蔽码设置为原来的屏蔽字,然后sigsuspend函数才返回。 Sigsuspend总是返回-1。 

 

例子:

#include<stdio.h>

#include<unistd.h>

#include<signal.h>

 

void deal()

{

   printf(“处理信号SIGINT\n”);

}

 

void main()

{

        signal(SIGINT,deal);

 int sum=0;

//声明信号集

sigset_t sigs;

sigset_t sigp;

sigset_t newsig=NULL;

//清空信号集

sigemptyset(&sigs);

//添加信号到信号集

sigaddset(&sigs,SIGINT); //

//屏蔽信号

sigprocmask( SIG_BLOCK,&sigs,0);

for(i=1;i<=10;i++)

{

     sum+=i;

     sigpending(&sigp);//得到屏蔽的信号

    if(sigismemeber(&sigp,SIGINT))

     {

           printf(“信号SIGINT在排队\n”);

           sigsuspend(&newsig);//切换屏蔽信号,等待SIGINT信号,并调用处//理函数后函数返回。

     }

     sleep(1);

}

printf(“sum=%d\n”,sum);

}

 

说明:程序检查到屏蔽信号中有SIGINT信号在排队,就调用sigsuspend函数切换屏蔽信号,程序处理SIGINT信号后,sigsuspend函数才返回。                                        

posted on 2013-08-12 19:25  风言枫语  阅读(893)  评论(0编辑  收藏  举报