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

    运行截图

  • 相关阅读:
    Git简介
    Git之 git status、git diff 的基本使用
    Git之撤销修改 git checkout file、git reset HEAD file 的使用
    git连接gitlab远程仓库
    Git版本回退及 git log 、 git reset hard commit_id 的基本使用
    Git创建版本库及git init 、add 和 commit m 的基本使用
    Git之工作区和暂存区
    Git的由来及分布式版本控制和集中式版本控制的区别
    MariaDB 主从同步与热备
    MariaDB 用户与权限管理
  • 原文地址:https://www.cnblogs.com/yuluoluo/p/8995087.html
Copyright © 2020-2023  润新知