信号量处理有关的函数和数据结构

1 kill和raise函数

#include<signal.h>
int kill(pid_t pid,int signo);//pid>0 将信号发送给进程ID==PID的进程
//pid==0 讲信号发送给其进程组ID等于发送进程的进程组ID的进程组

kill函数将信号量发送给进程或者进程组,raise函数允许进程向自身发送信号,我们常在终端下杀死一个进程使用kill -9 [pid],这实际上是调用了kill函数给[pid]发送了一个SIGKILL信号量,并且这个信号量不能捕捉,不能忽略,也就是[pid]这个进程收到这个信号就必须得死,如果权限足够的情况下。

2 alrm和pause函数

unsigned int alrm(unsigned int seconds);
int pause(void);

alrm函数设定一个时间值,比如alarm(5),五秒之后将会产生SIGALRM信号,如果不捕捉这个信号,当前进程将会终止。

int main()
{
    signal(SIGALRM,fun);//注册了捕捉函数后,闹钟时间到进入处理函数,如果注释掉这句,闹钟时间到会终止当前进程
    alarm(5);
    while(1);
}
void fun(int signo)
{
    cout<<"收到了alarm信号"<<endl;
}

pause函数使调用进程挂起,直到捕捉到一个信号,只有执行了一个信号处理程序并从其返回时,pause才返回,这种情况下pause返回-1;

int main()
{
    signal(SIGALRM,fun_sigint);
    cout<<"pause在等待信号处理程序"<<endl;
    alarm(5);
    pause();//进程会阻塞在这里,直到fun函数返回
    cout<<"pause函数返回了"<<endl;
    while(1);


}

void fun(int signo)
{
    cout<<"收到了alarm信号"<<endl;
}

3 信号集

这是一个数据结构,这个数据结构中保存了很多信号

sigset_t set;
int sigemptyset(sigset_t *set);//清空当前信号集合
int sigaddset(sigset_t *set,int signo);//将信号量signo添加到信号集中
int sigismember(const sigset_t *set,int signo);//信号signo在信号集返回1,否则返回0

4 sigprocmask函数

int sigprocmask(int how,const sigset_t *set,sigset_t *oset);

//set是一个信号集,根据前边的how决定如何处理这个集中的信号(屏蔽set中的信号,解除屏蔽),oset返回一个集合,这个集合记录了当前进程屏蔽了哪些信号,关于how:
//SIG_BLOCK :屏蔽set信号集中所有的信号
//SIG_UNBLOCK :该进程新的屏蔽字是当前的屏蔽字和set指向的信号的交集
//SIG_SETMASK :该进程新的信号屏蔽字是set指向的值
int main()
{
    sigset_t set;
    sigemptyset(&set);//清空set
    sigaddset(&set,SIGINT);//将ctrl+c添加到set中
    sigprocmask(SIG_BLOCK,&set,NULL);//屏蔽此信号集中的信号
    while(1);

}

运行以上代码,在终端ctrl+c,当前进程就不会退出了。杀掉此进程的方法是:kill -9 [pid]; 或者:

int main()
{
    kill(10314,9);//10314是要杀死的进程的pid.
}

5 sigpending函数

int sigpending(sigset_t *set);//返回当前进程被阻塞不能传递的信号集,通过set(传指针)返回,成功函数返回0,出错返回-1.

6 sigaction函数

我们先来看看sigaction这个结构体:

struct sigation
{
    void (*sa_handler)();//信号处理函数
    sigset_set sa_mask;//屏蔽字
    int sa_flags;
}

//sigation函数
int sigaction(int sigo,const struct sigaction *act,struct sigaction *oact);

这个我们可以理解为高级版的signal函数,可以修改其屏蔽字,处理函数。

int main()
{
    struct sigaction action;
    action.sa_handler=fun_sigint;//设置信号处理函数
    action.sa_flags=0;
    sigemptyset(&action.sa_mask);//清空屏蔽字
    sigaddset(&action.sa_mask,SIGINT);//添加SIGINT到屏蔽字中
    sigprocmask(SIG_BLOCK,&action.sa_mask,NULL);//屏蔽屏蔽集中的信号
    sigaction(SIGQUIT,&action,NULL);//捕捉SIGQUIT信号
    while(1);

}

void fun_sigint(int signo)
{
    cout<<"SIGQUIT"<<endl;
}

7 sigsetjmp和siglongjmp函数

类似与setjmp和longjmp,遇到longjmp直接跳转回到setjmp处,适用于函数间的跳转,只不过这里是从信号处理函数中直接跳转到上一个函数中设置sigsetjmp处。例如:

void func1()
{
    signal(SIGINT,sigfunc);
    //1
    sigsetjmp(buf,savemask);<<<------------------
    //2                                         |
}                                               |
int sigfunc(int sigo)                           |
{                                               |
    ...//信号处理函数                             |
    siglongjmp(buf,val);---------------------->>>
    //这后边的代码都不会执行了
}

8sigsuspend函数

int sigsuspend(const sigset_t *sigmask); //屏蔽sigmask中的信号量,并且阻塞,直到从任何一个信号处理函数返回
int main()
{
    sigset_t set;
    signal(SIGQUIT,fun_sigint);
    sigemptyset(&set);
    sigaddset(&set,SIGINT);
    sigsuspend(&set);//阻塞,并且屏蔽掉SIGINT信号
    while(1);

}

void fun_sigint(int signo)
{
    cout<<"进入了处理函数"<<endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值