用到的信号函数和有关信号的东西

用到的信号函数和有关信号的东西
异步:

一种通讯方式,对设备要求简单。我们的PC机提供的标准通讯接口都是异步的。

异步双方不需要共同的时钟,也就是接收方不知道发送方什么时候发送,所以在发送的信息中要有提示接收方开始接受的信息,如开始位,同时在结束时有停止位。

异步的另一种含义:计算机多线程的异步处理。与同步处理相对,异步处理不用阻塞当前线程来等待处理完成,而是允许后续操作,直到其他线程将处理完成,并回调通知此线程。

信号的来源:

产生条件:硬件和软件

硬件:

  • 终端上按下某些键,将产生信号。
  • Ctrl+C产生一个SIGINT信号
  • 硬件异常产生信号:
  • 除数为0,无效的存储访问
  • 这些事件通常由硬件(CPU)检测到,并将其通知给Linux操作系统内核,然后内核生成相应的信号,并把信号发送给该事件发生时正在运行的程序。

软件:

  • 用户在终端下调用kill命令向进程发送任意信号
  • 进程调用kill或sigqueue函数发送信号
  • 当检测到某种软件条件已经具备时发出信号,如由alarm或settimer设置的定时器超时将生成SIGALRM信号
信号的种类

Linux系统下支持的信号种类有64种,定义在#include<signal.h>

在书上P221,很详细,就列出几个我用到的信号

  • 信号:

    • SIGINT:用户按下了<Ctrl+C>组合键时,用户终端向正在运行中的由该终端启动的程序发出此信号,默认动作为终止此进程。

    • SIGQUIT:用户按下<Ctrl+\>组合键时产生该信号,用户终端向正在运行中的由该终端启动的程序发出此信号,默认动作为终止进程并产生core文件。

    • core文件是什么?

    当我们程序崩溃时,内核有可能把该程序当前内存映射到core文件里,方便程序员找到程序找到出现问题的地方。

    当一个程序崩溃时,在晋城当前工作目录的core文件中复制了该进程的存储图像。core文件仅仅是一个内存映像(同时加上调试信息),主要是用来调试的。

    • SIGPIPE:向一个没有读端的管道写数据,默认动作为终止进程。
信号处理
  • signal

    • 原型:
    
    #include<signal.h>
    
    typedef void (*sighandler_t)(int);
    sighandler_t signal(int signum,sighandler_t handler);
    • 作用:用来设置进程在接收到信号时的动作

    • 参数:

    • 根据signum指定的信号编号来设置该信号处理函数。

      • 当指定的信号到达时就会跳转到参数handler指定的参数执行。
      • 如果参数handler不是函数指针,则必须是常数SIG_IGN(忽略该信号)或SIG_DFL(对该信号执行默认操作)
    • handler:一个函数指针,它所指向的函数的类型是sighandler_t,即它所指向的函数有一个int型的参数,且返回值的类型为void

    • 执行情况返回值
      成功返回以前的信号处理函数指针
      失败返回SIG_ERR(即-1)
    • 注意:SIGKILL和SIGSTOP两个信号不能被捕捉或忽略

    
    #include<stdio.h>
    
    
    #include<signal.h>
    
    /*信号处理函数*/
    void handler_sigint(int signo)
    {
      printf("recv SIGINT\n");
    }
    int main(void)
    {
      /*安装信号处理函数*/
      signal(SIGINT,handler_sigint);
      while(1)
      {
          ;
      }
      return 0;
    }

    ![2018-08-14 17-12-04 的屏幕截图](/home/lala/图片/2018-08-14 17-12-04 的屏幕截图.png)

    程序首先使用signal安装信号SIGINT的处理函数handler_sigint函数,然后进入死循环。当接收到信号时,程序自动跳转到信号处理函数处执行,打印出提示消息,然后返回主函数继续执行死循环。

信号屏蔽

POSIX标准定义了数据类型sigset_t来表示信号集,并且定义了一系列函数来操作信号集。

信号集
#include<signal.h>
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set,int signum);
int sigdelset(sigset_t *set,int signum);
int sigismember(const sigset_t *set,int signum);
  • 函数的具体含义:

    • sigemptyset:用来初始化一个信号集,使其不包括任何信号。
    • sigfillset:用来初始化一个信号集,使其包括所有信号。
    • sigaddset:用来向set指定的信号集中添加由signum指定的信号。
    • sigdelset:用来从set指定的信号集中删除由signum指定的信号。
    • sigismember:用来测试信号signum是否包括在set指定的信号集中。
  • 执行情况返回值
    成功返回0
    失败返回-1

    以上是除过sigismember的函数的执行情况

返回值含义
1表示测试的信号在信号集中
0表示测试的信号不在信号集中

上面这个是sigismember的函数的执行情况

信号屏蔽

信号屏蔽又称信号阻塞

#include<signal.h>
int sigprocmask(int how,const sigset_t *set,sigset_t *oldset);
int sigpending(sigset_t *set);
int sigsuspend(const sigset_t *mask);
  • 函数解析:

    • sigprocmask函数;

    • 每个进程都有一个信号屏蔽吗,它规定了当前阻塞而不能递送给该进程的信号集。调用函数可以监测或更改进程的信号屏蔽码。如果参数oldset是非空指针,则进程之前的信号屏蔽码通过oldset返回;如果set是非空指针,则函数将根据参数how来修改信号当前的屏蔽码。

    • how:
    how含义
    SIG_BLOCK奖金诚信的信号屏蔽码设置为当前信号屏蔽码和set指向的信号集的并集
    SIG_UNBLOCK将进程新的信号屏蔽码设置为当前信号屏蔽码中,删除set所指向的信号集,即set包含了我们希望接触阻塞的信号。既是对当前信号屏蔽码中存在的信号使用SIG_UNBLOCK也是合法操作
    SIG_SETMASK将进程新的信号屏蔽码设置为set指向的值
    执行情况返回值
    成功0
    失败-1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值