信号
信号的基本操作
发送信号
递送信号
捕获信号
屏蔽信号
忽略信号
处理信号
Linux 中的信号
1 如何发起异步操作
》 kill (kill 命令 eg: kell -signum pid。
函数:int kell(pid,signum);)
pid > 0 : 信号发给pid进程
pid = 0 : 发给当前进程组的所有进程
pid = -1: 发送给系统内所有进程
pid < 0 : 发送给|pid| 所对应的进程组组
//查看进程号进程组的函数
pid = getpid ();
gpid = getgpid();
》 raise 自举信号,会给自己发送一个信号
int raise(int sig);// 一般用在唤醒某些进程里的函数
等同于 int kill (getpid(),signum);
》 alarm
定时函数:
unsigned int alarm(unsigned int seconds);
函数会在所指定的seconds 之后收到SIGALRM信号
》ualarm
useconds_t ualarm (useconds_t usecs,useconds_t interval);
以useconds 为单位,第一个参数为第一次产生时间,第二个参数为间隔产生
》 signal
signal (signum,handler/中断服务函数/)
》setitimer 定时器(标准的)
getitimer (int which , struct itimerval * curr_value);
setitimer ();
Linux 会给进程提供三个定时器
1 . ITIMER_REAL: 以逝去时间递减
2 . ITIMER_VIRTUAL: 当进程自身代码执行时才会递减(系统函数不算)
3 . ITIMER_PROF:
如何安装和捕获信号
》忽略信号
》自定义捕捉函数(SIGKILL,SIGSTOP 两个信号无法捕捉)
》系统默认信号函数
signal
signal (signum,handler/中断服务函数/)
//SIGSTOP SIGKILL 不能被安装
忽略信号
signal (signum,SIG_IGN);//直接丢掉
高级信号用法
sigset_t 信号集合
信号会唤醒当前进程的阻塞状态(pause函数就会被唤醒,sleep()不会)
- sa_flag
信号集合
- sigset_t sa_mask;
信号集合相关操作函数
int sigemptyset();//清空信号集
int sigfillset();//将制定信号集置1
int sigaaddset();//将某个信号加入指定信号集
int sigdelset();//将某个信号从信号集中删除
int sigismember();//判断某个信号是否被加入指定信号集
-
设置信号屏蔽函数
-
sigprocmask(int how,const sigset_t *set,sigset_t * oldset);
-
how:
SIG_BLOCK //追加
SIG_UNBLOCK //删除 从信号集合中删除
SIG_SETMASK //重置,覆盖
未决信号 (未捕获,忽略,屏蔽的信号)
相关链接
sigpending(sigset)//可以查看未决信号
sigsuspend 函数
相关链接
int sigsuspend (const sigset_t * mask);
代码
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<unistd.h>
//SIGUSR1 信号处理函数
void sig_usr1(int sig)
{
printf("I am SIGUSR1
");
}
void sig_usr2(int sig)
{
printf("I am SIGUSR2
");
}
void sig_int(int sig)
{
printf("catch signal :%d
",sig);
sleep(1);
}
//打印信号集 1--31 号信号
void print_sig(sigset_t *p)
{
int i = 1;
for(;i < 32;++i){
if(sigismember(p,i)){
printf("1");
}else{
printf("0");
}
}
printf("
");
}
int main ()
{
printf("MY pid is %d
", getpid());//获得当前进程的pid,以便在终端进行代码测试
//信号集
sigset_t newmask,oldmask,penmask,susmask;
struct sigaction newact,oldact,susact;
//signal(SIGINT,sig_int);//捕获信号SIGINT,并与sig_int函数绑定
//sigaction 结构体的设置
newact.sa_handler = sig_int;//还有一种 newact.sa_flags = SA_SIGINFO; newact.sa_sigaction =func;
sigemptyset(&newact.sa_mask);//清空该信号集
//sigaddset(&newact.sa_mask,SIGINT);//将SIGINT信号加入sa_mask 信号集中,在信号处理函数执行时,将屏蔽SIGINT
newact.sa_flags = 0;//屏蔽自身所发信号,sa_flags 还有其他取值
sigaction(SIGINT,&newact,&oldact);//oldact会保存旧的信息处理函数等信息,起到备份作用。
//对SIGUSR1 和 SIGUSR2 绑定信号处理函数
signal(SIGUSR1,sig_usr1);
signal(SIGUSR2,sig_usr2);
//屏蔽信号
sigemptyset(&newmask);
sigaddset(&newmask,SIGUSR1);//将SIGUSR1信号加入到newmask 信号集中
//sigdelset(&newmask,SIGUSR1);//删除该信号
sigprocmask(SIG_BLOCK,&newmask,&oldmask);//SIG_BLOCK 将newmask 中信号屏蔽还有其他取值:SIG_UNBLOCK 、SIG_SETMASK
sigemptyset(&susmask);
sigaddset(&susmask,SIGUSR2);
//用susmask信号集替换原来的信号屏蔽字,也就是SIGUSR1 不在被屏蔽,SIGUSR2被屏蔽,
//当发送非SIGUSR2信号时,恢复为SIGUSR1的屏蔽,函数返回,不在阻塞
sigsuspend(&susmask);
printf("free
");
//解除屏蔽 注释点才能显示SIGUSR1的未决信号
//sigprocmask(SIG_SETMASK,&oldmask,NULL);
while(1)
{
sigpending (&penmask);//获取当前进程中的未决信号集信息,如果现在发送SIGUSR1信号,那么sigpending 可以获得。
print_sig(&penmask);//打印出获取到的未决信号
sleep(3);
}
return 0;
}