• 屏蔽信号的多路选择I/O


     

    前边提到了多路I/O的方法,这一章屏蔽信号的多路选择与之前的多路I/O一致,只是增加了屏蔽信号的作用。多路选择I/O中我们使用的是select函数,屏蔽信号的多路选择I/O使用的是pselect函数,与之前的函数相比,增加了一个参数可以用来屏蔽信号。具体函数如下所示:

     int pselect(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, const struct timespec *timeout, const sigset_t *sigmask); 

    头文件: #include <sys/select.h> 

    参数说明:前4个参数与select函数的参数相同,分别表示最大的文件描述符和关心的文件中状态。

    第5个参数表示等待时间,所不同的是timespec结构所能表示的最小精度是纳秒,旧的结构体中所能表示的最小精度是微妙数。

    pselect函数最后一个参数可以用来屏蔽信号,在pselect函数返回后,再将屏蔽的信号恢复,并且所有的操作都是原子的。

    返回值:超时返回0,出错返回-1,成功返回描述字的个数。

    下面用两个程序的对比来说明select函数与pselect函数的区别。

    第一个程序使用select函数,程序中人为的制造了一个造成函数阻塞的条件。该程序在阻塞的时候会被信号中断。

    #include <stdio.h>
    #include <sys/select.h>
    #include <stdlib.h>
    #include <signal.h>
    /* SIGUSR1的信号处理函数 */
    void sigusr1_handler(int signo)
    {
           printf("catch SIGUSR1
    "); /* 接收SIGUSR1信号,打印接收信息 */
    }
    int main()
    {
           int rdy; /* 准备好的设备数 */
           /* 注册信号处理函数,如果捕捉到信号则输出提示信息 */
           if(signal(SIGUSR1, sigusr1_handler) == SIG_ERR){
                  perror("can’t set handler for SIGUSR1");
                  exit(1);
           }
           /* 不关心所有的设备准备状态,所以检查设备的最大文件描述符的值也不再有意义。
           * 等待时间结构为NULL,表示将等待时间设置为无限等待
           */
           rdy = select(1, NULL, NULL, NULL, NULL);
           /* 因为是无限等待,所以绝对不应该执行到这里,输出提示信息 */
           printf("should never be here
    ");
           return 0;
    }

    第二个程序使用pselect函数,程序中人为的制造了一个造成函数阻塞的条件。该程序在阻塞的时候不会被信号中断。

    #include <stdio.h>
    #include <sys/select.h>
    #include <stdlib.h>
    #include <signal.h>
    /* SIGUSR1的信号处理函数 */
    void sigusr1_handler(int signo)
    {
           printf("catch SIGUSR1
    "); /* 接收SIGUSR1信号,打印接收信息 */
    }
    int main()
    {
           int rdy;                                /* 准备好的设备数 */
           sigset_t set;                         /* 信号集 */
             /* 注册信号处理函数,如果捕捉到信号则输出提示信息 */
           if(signal(SIGUSR1, sigusr1_handler) == SIG_ERR){
                  perror("can’t set handler for SIGUSR1");
                  exit(1);
           }
           sigfillset(&set); /* 设置信号集,屏蔽所有的信号,包括SIGKILL和SIGSTOP */
           /* 不关心所有的设备准备状态,所以检查设备的最大文件描述符的值也不再有意义。
           * 等待时间结构为NULL,表示将等待时间设置为无限等待
            */
           rdy = pselect(1, NULL, NULL, NULL, NULL, &set);
           /* 因为是无限等待,所以绝对不应该执行到这里,输出提示信息 */
           printf("should never be here
    ");
           return 0;
    }

    在调试的时候用kill命令向进程发送SIGUSR1信号,观察输出结果,通过两个程序运行的对比可以清楚的理解pselect函数和select函数的区别。

  • 相关阅读:
    centos7.2安装配置
    CentOS系统操作mysql的常用命令
    MySQL5.7安装与配置(YUM)
    排序的空间复杂度和尾递归小记
    常见内排序实现汇总(含部分优化实现,基于链表的实现),以及性能比较
    [ASP.NET]从ASP.NET Postback机制,到POST/GET方法
    内存管理笔记(分页,分段,逻辑地址,物理地址与地址转换方式)
    [EXT JS]"hasMany" association on ExtJS 4.1.1a
    使用nodejs抓取博客园内容---Promise模块探索
    NodeJs + mongodb模块demo
  • 原文地址:https://www.cnblogs.com/Mr--Yang/p/6822545.html
Copyright © 2020-2023  润新知