系统编程之进程间的信号(system)通信(2)

系列文章目录

第一章 系统编程之多进程

第二章 系统编程之进程间的 管道 通信(1)

第二章 系统编程之进程间的 信号 通信(2)

第二章 系统编程之进程间的 共享内存 通信(3)

第二章 系统编程之进程间的 信号量 通信(4)

第二章 系统编程之进程间的 消息队列 通信(5) 

目录

系列文章目录

前言

一 信号

1 信号总共有四种响应方式:

2 信号的默认响应动作

2.1 绝大部分信号:默认动作都是终止程序,比如下面四个信号

2.2 发送信号的常用命令:

3 相关的接口函数 

3.1 信号的发送 kill()

3.2 捕捉信号并改变信号的响应动作(重点)

3.3 raise()和alarm() 

3.4  阻塞进程,等待信号的到来 

3.5 信号的发送和捕捉函数

总结

前言

信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。

一 信号

linux通过信号去控制进程的行为动作(程序的退出,程序的暂停,程序的继续),Linux通过以下命令可以查看信号的情况。

(1) 1--31号信号:非实时信号, 能嵌套  

signal(SIGINT,fun)    

void  fun(int num)

{  

         signal(SIGQUIT,otherfun);    

}

(2) 34--64号信号(新增):实时信号,不能嵌套 

1 信号总共有四种响应方式:

  • 信号的默认响应动作(就是linux系统已经规定好的)
  • 改变信号的响应动作
  • 信号的忽略
  • 信号的阻塞(信号的屏蔽)

2 信号的默认响应动作

2.1 绝大部分信号:默认动作都是终止程序,比如下面四个信号

SIGINT ---》ctrl+c  就是给当前进程发送了SIGINT信号
SIGSTOP ---》程序暂停
SIGCONT ---》程序继续
SIGKILL ---》杀死进程

2.2 发送信号的常用命令:

kill  -信号的序号   进程的ID
kill  -信号的名字   进程的ID
kill  -9   hello
kill -SIGKILL  hello
kill -KILL hello


killall  -信号的序号   进程的名字
killall  -信号的名字   进程的名字
killall  -9   hello
killall -SIGKILL  hello
killall -KILL hello

3 相关的接口函数 

3.1 信号的发送 kill()

#include <signal.h>
int kill(pid_t pid, int sig);
参数:pid --》进程的ID号
           sig --》信号的序号

3.2 捕捉信号并改变信号的响应动作(重点)

// 给  void (*)(int)类型的函数指针换了名字,名字叫做 sighandler_t

typedef void (*sighandler_t)(int);  
参数:表示捕捉到的信号的序号

//实际应用:保护你的代码不受干扰,可以收到信号以后按照程序员的逻辑去执行新的代码

sighandler_t  signal(int  signum,  sighandler_t  handler);  
返回值:成功 返回函数指针
               失败 NULL
参数:signum --》你要捕捉的信号的序号
           handler --》函数指针 

signal函数总共有三个功能
功能一:改变信号的响应动作
功能二:SIG_IGN  忽略信号,信号发送给进程,进程直接舍弃,左耳进右耳出
功能三:SIG_DFL  按照信号默认的动作响应

注意:SIGKILL和SIGSTOP这两个信号既不能改变它们的响应动作,也不能忽略,其他的信号可以

3.3 raise()和alarm() 

int raise(int sig);    //自己给自己发信号    

raise(9);                  // 等价于kill(getpid(),信号的序号)
 

unsigned int alarm(unsigned int seconds);         //定时器
参数:seconds --》单位是秒
比如:  alarm(5);         //间隔5秒钟给当前进程发送SIGALRM信号

3.4  阻塞进程,等待信号的到来 

int pause(void);  //信号不来 ,一直阻塞

3.5 信号的发送和捕捉函数

linux中有两组常用的信号发送和捕捉函数

  • kill和signal
  • sigqueue和sigaction  (升级版)

//给进程发送信号,同时携带额外

int  sigqueue(pid_t  pid, int sig, const union sigval  value)  数据
参数:  

union sigval {
        int   sival_int;  //你要发送给进程的数据
        void *sival_ptr;  //你要发送给进程的一个首地址
 };


//捕捉信号,改变信号的响应动作                     

int sigaction(int signum, const struct sigaction *act,  struct sigaction *oldact);  
参数:(重点)

struct sigaction {   
        void     (*sa_handler)(int);         // 函数指针 1
        void     (*sa_sigaction)(int, siginfo_t *, void *);        // 函数指针 2
        sigset_t   sa_mask;                                                 //存放你要阻塞的信号
        int   sa_flags;    //  开关:设置SA_SIGINFO 选择函数指针 2,设置0选函数指针 1响应                                                  
        void     (*sa_restorer)(void);                                 //保留字段,没有什么用
};
act --》保存你设置的信号响应函数
oldact  --》(做备份的)保存当前进程原本设置的信号响应函数

void     (*sa_sigaction)(int, siginfo_t *, void *); //函数指针 2
参数:int --》你捕捉的信号的序号
           siginfo_t --》结构体指针,用来存放sigqueue发送过来的额外数据
            {
                 int si_int; //保存发送过来额外数据
                 void *si_ptr;  //保存发送过来的指针
            }

总结

本文主要讲解了进程间信号通信的原理和相关的接口函数。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值