select与pselect的信号屏蔽

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被信号中断,经我测试,两者还是有区别的,第一种当你在终端输入数据时,时钟信号处理函数是会被执行的,而第二种则彻底屏蔽了时钟信号。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值