Linux编程--信号

信号

信号的基本操作

发送信号
递送信号
捕获信号
屏蔽信号
忽略信号
处理信号

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);//直接丢掉

高级信号用法

sigantion 对象---转载

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\n");
}

void sig_usr2(int sig)
{
  printf("I am SIGUSR2\n");
}

void sig_int(int sig)
{
	printf("catch signal :%d\n",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("\n");
}


int main ()
{
   printf("MY pid is %d\n", 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\n");
  
  //解除屏蔽 注释点才能显示SIGUSR1的未决信号
  //sigprocmask(SIG_SETMASK,&oldmask,NULL); 

  while(1)
  {
    sigpending (&penmask);//获取当前进程中的未决信号集信息,如果现在发送SIGUSR1信号,那么sigpending 可以获得。
    print_sig(&penmask);//打印出获取到的未决信号
    sleep(3);
  }
 return 0;
}

运行截图

posted @ 2018-05-05 16:29  雨落洛  阅读(416)  评论(0编辑  收藏  举报