pselect() 函数的原型是:int pselect(int nfds, fd_set *readfds, fd_set *writefds,
                   fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask);
它和 select() 函数基本相同,区别在于两个不同的参数,一个是 struct timespec *timeout,另一个是 sigset_t *sigmask 。

struct timespec 结构定义为:
  struct timespec {
               long    tv_sec;         
               long    tv_nsec;        
           };

其中的时间表示秒和纳秒。和 select() 不同,每次超时后,pselect() 并不会去修改这个时间参数,也就是说,没有必要再次对这个时间参数进行初始化。
对于最后一个参数 sigmask 表示信号屏蔽掩码,设置掩码可以对相应的信号进行屏蔽,这样pselect就一直不会被屏蔽的信号所中断。

select等待期间不想被中断的方法有两个:

其一:pselect 代替select

#include "unp.h"

void
sig_alarm(int signo)
{
        printf("%d\n",signo);
        if(signo == SIGALRM)
        {
                printf("SIGALRM\n");
        }
        else if(signo == SIGVTALRM)
        {
                printf("SIGVTALRM\n");
        }
}

int
main()
{
        sigset_t sigmask;
        fd_set rset;
        ssize_t nread;
        char buf[MAXLINE];
        int maxfd;
        struct itimerval value;
        signal1(SIGALRM,sig_alarm);

value.it_interval.tv_sec = 3;
        value.it_interval.tv_usec = 0;
        value.it_value.tv_sec = 1;
        value.it_value.tv_usec = 0;
        if(setitimer(ITIMER_REAL,&value,NULL) == -1)
        {
                printf("setitimer error.\n");
                return 0;

}

if(sigemptyset(&sigmask) ==  -1)
        {
                printf("sigemptyset error.\n");
                return 0;
        }

if(sigaddset(&sigmask,SIGALRM) == -1)
        {
                printf("sigaddset error.\n");
                return 0;
        }
        while(1)
        {
                FD_ZERO(&rset);
                FD_SET(fileno(stdin),&rset);
                maxfd = fileno(stdin) + 1;

int nready = pselect(maxfd,&rset,NULL,NULL,NULL,&sigmask);
                //printf("select called.%d\n",nready);
                if(nready < 0)
                {
                        if(errno == EINTR)
                        {
                                printf("interruped.\n");
                        }
                }
                else
                {
                        int nread = ReadLine(fileno(stdin),buf,MAXLINE);
                        if(nread < 0)
                        {
                                printf("读取失败!\n");
                                continue;
                        }
                //      printf("nread: %d\n",nread);
                        //Write(stdin,buf,nread);
                        printf("%s",buf);
                }
        }
}

其二:运用sigprocmask函数

#include "unp.h"

void
sig_alarm(int signo)
{
        printf("%d\n",signo);
        if(signo == SIGALRM)
        {
                printf("SIGALRM\n");
        }
        else if(signo == SIGVTALRM)
        {
                printf("SIGVTALRM\n");
        }
}

int
main()
{
        sigset_t sigmask;
        fd_set rset;
        ssize_t nread;
        char buf[MAXLINE];
        int maxfd;
        struct itimerval value;
        signal1(SIGALRM,sig_alarm);

value.it_interval.tv_sec = 3;
        value.it_interval.tv_usec = 0;
        value.it_value.tv_sec = 1;
        value.it_value.tv_usec = 0;
        if(setitimer(ITIMER_REAL,&value,NULL) == -1)
        {
                printf("setitimer error.\n");
                return 0;

}

if(sigemptyset(&sigmask) ==  -1)
        {
                printf("sigemptyset error.\n");
                return 0;
        }

if(sigaddset(&sigmask,SIGALRM) == -1)
        {
                printf("sigaddset error.\n");
                return 0;

}

sigprocmask(SIG_BLOCK,&sigmask,NULL);

while(1)
        {
                FD_ZERO(&rset);
                FD_SET(fileno(stdin),&rset);
                maxfd = fileno(stdin) + 1;

//int nready = pselect(maxfd,&rset,NULL,NULL,NULL,&sigmask);

//printf("select called.%d\n",nready);

int nready = select(maxfd,&rset,NULL,NULL,NULL);

if(nready < 0)
                {
                        if(errno == EINTR)
                        {
                                printf("interruped.\n");
                        }
                }
                else
                {
                        int nread = ReadLine(fileno(stdin),buf,MAXLINE);
                        if(nread < 0)
                        {
                                printf("读取失败!\n");
                                continue;
                        }
                //      printf("nread: %d\n",nread);
                        //Write(stdin,buf,nread);
                        printf("%s",buf);
                }
        }

}

比较两种方法,都可以有效防止select被信号中断,经我测试,两者还是有区别的,第一种当你在终端输入数据时,时钟信号处理函数是会被执行的,而第二种则彻底屏蔽了时钟信号。

select与pselect的信号屏蔽相关推荐

  1. 【Linux】延时函数sleep、usleep、nanosleep、select、pselect的比较

    1.简介 sleep()-------以秒为单位 #include<unistd.h> unsigned int sleep(unsigned int seconds); return:若 ...

  2. linux进程中对信号的屏蔽,linux进程中的信号屏蔽

    在linux的进程中可以接收到各种的信号,并且如果你不对信号进行处理,linux中的进程就会采用默认的处理方式处理,比如ctrl-c的信号,进程对它的处理就是终止进程的执行. 在linux中,我们也可 ...

  3. 210124阶段三信号屏蔽,管道通信

    目录 一.学习的知识点 1屏蔽信号 2管道 2.1匿名管道 2.2命名管道 二.上课没有听懂或者没有理解的地方 三.当天学习的收获 一.学习的知识点 64个信号源 前32个信号 每个信号都有对应的函数 ...

  4. Linux系统编程----7(信号集,信号屏蔽,信号捕捉)

    信号集操作函数 内核通过读取未决信号集来判断信号是否应被处理.信号屏蔽字 mask 可以影响未决信号集.而我们可以在应 用程序中自定义 set 来改变 mask.已达到屏蔽指定信号的目的. 信号集设定 ...

  5. 手机信号屏蔽器的设计与制作

    2007-12-25 13:39:55 前些时候,有朋友送来一台<手机信号屏蔽器>,故障是对CDMA手机不起作用,我看了一下说明书,该机应该能够干扰四个频段: CDMA:869-894MH ...

  6. 干扰网络信号的app_手机信号屏蔽软件?告诉你一个「真实有效」的屏蔽信号方法...

    屏蔽手机信号就是通过某种利用某种设备或是某种方法使手机信号暂时消失或减弱的一种行为,多用于教育部门考试.国家机密机关以及机密项目的保密工作中.近年来随着手机等移动终端的日益普及,家庭使用屏蔽设备对无线 ...

  7. 子进程信号继承;kill+raise+alarm+pause+信号发生接收和处理+信号屏蔽

    子进程对父进程信号继承情况 fork创建子进程,但子进程没有exec 在fork子进程之前: 如果父进程调用signal设置了某个信号的处理方式的话,那么fork出的子进程会继承父进程对该信号设置的处 ...

  8. linux设置子线程的信号屏蔽器,[转载]linux信号屏蔽字

    1. 概念: 信号屏蔽字就是进程中被阻塞的信号集, 这些信号不能发送给该进程, 它们在该进程中被"屏蔽"了. 后面我们会提到, 实际上它们是被阻塞了. 2. 信号屏蔽函数: #in ...

  9. 32.全网最详细trap讲解,trap语法格式,信号和用途,最常用的信号,trap常用的命令,ctrl + c,信号屏蔽和恢复,trap -,debug,exit,return示例,三个综合案例

    文章目录 语法详解 trap格式 信号和用途 最常用的信号 trap常用的命令 示例 ctrl + c 示例 信号屏蔽和恢复 trap - 示例 debug示例 exit示例 return示例 综合案 ...

最新文章

  1. AI 一分钟 | 谷歌发布72量子比特处理器,或将为机器学习应用提供加速;百度已经发起对景驰撤诉,但不会对王劲撤诉
  2. TensorRT部署深度学习模型
  3. Containers vs Serverless:怎么选择?
  4. win2003禁止web等目录执行exe,bat,com的方法
  5. Codeforces 919D - Substring
  6. iOS传感器之气压计的使用
  7. OceanBase数据库实践入门——性能测试建议
  8. C++中枚举的用法(比较全面)(转)
  9. 第一章:React入门
  10. VS2010 工具箱组件添加重复
  11. ES6的新特性(5)——数值的扩展
  12. android初始化activity时隐藏软键盘
  13. GridControl 设置自带选中复选框及设置该列列头名称
  14. java实现的判断括号是否成对的代码,()[]{}都可以
  15. 编译GDAL支持ArcObjects
  16. java-设计模式(行为型)-【命令模式】
  17. 解决办法:发生故障,这可能是有软件包被要求保持现状的缘故
  18. pyqt5 点击开始执行_PyQt5教程——第一个程序(2)
  19. Mysql 驱动包mysql-connector-java-8.0.25.jar下载
  20. c fread 快读 详解_热量计算公式及例题详解

热门文章

  1. oracle 监听 无法连接,oracle监听hang,无法建立新连接TNS-12540
  2. centos yum 安装python3.6+pip
  3. Spring Cloud Gateway Predicate.Path过滤分析
  4. js 数字千分位展示
  5. 实验一 链式存储结构的基本操作
  6. 计算机网络协议包头赏析-TCP
  7. html中水印影响文字复制,HTML中文字水印的清除方法_HTML教程
  8. java提高篇四_(转)java提高篇(四)-----理解java的三大特性之多态
  9. Spring Boot----SpringBoot整合 Dubbo 和 Zookeeper
  10. POJ 1276 完全背包