博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
select与pselect的信号屏蔽
阅读量:4149 次
发布时间:2019-05-25

本文共 2908 字,大约阅读时间需要 9 分钟。

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

转载地址:http://jfpti.baihongyu.com/

你可能感兴趣的文章
[LeetCode]Maximal Rectangle
查看>>
[LeetCode]Maximum Subarray
查看>>
[LeetCode]Median of Two Sorted Arrays
查看>>
[LeetCode]Merge Intervals
查看>>
[LeetCode]Merge k Sorted Lists
查看>>
[LeetCode]Merge Sorted Array
查看>>
[LeetCode]Merge Two Sorted Lists
查看>>
[LeetCode]Minimum Depth of Binary Tree
查看>>
[LeetCode]Minimum Path Sum
查看>>
[LeetCode]Minimum Window Substring
查看>>
[LeetCode]Multiply Strings
查看>>
[LeetCode]N-Queens II
查看>>
[LeetCode]Next Permutation
查看>>
[LeetCode]Palindrome Number
查看>>
[LeetCode]Palindrome Partitioning
查看>>
[LeetCode]Palindrome Partitioning II
查看>>
[LeetCode]Partition List
查看>>
[LeetCode]Pascal Triangle II
查看>>
[LeetCode]Permutations
查看>>
[LeetCode]Plus One
查看>>