select和pselect

int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

int pselect(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask);

selectpselect函数原型的说明:

Selectpselect都是等待一系列的文件描述符(int)的状态发生变化。

这两个函数基本上是一致,但是有三个区别:

第一点    select函数用的timeout参数,是一个timeval的结构体(包含秒和微秒),然而pselect用的是一个timespec结构体(包含秒和纳秒)

第二点    select函数可能会为了指示还剩多长时间而更新timeout参数,然而pselect不会改变timeout参数

第三点    select函数没有sigmask参数,当pselectsigmask参数为null时,两者行为时一致的。有sigmask的时候,pselect相当于如下的select()函数,在进入select()函数之前手动将信号的掩码改变,并保存之前的掩码值;select()函数执行之后,再恢复为之前的信号掩码值。

sigset_t origmask;

sigprocmask(SIG_SETMASK, &sigmask, &origmask);

select(nfds, &readfds, &writefds, &exceptfds, timeout);

sigprocmask(SIG_SETMASK, &origmask, NULL);

例如:

 1:sigset_t new, old, zero;
 2:
 3:sigemptyset(&zero);
 4:sigemptyset(&new);
 5:sigaddset(&new, SIGINT);
 6:sigprocmask(SIG_BLOCK, &new, old);//block SIGINT
 7:if (intr_flag)
 8:    handle_intr();//handle the signal
 9:if ((nready = pselet(..., &zero)) < 0){
10:    if (errno = EINTR){
11:        if (intr_flag)
12:            handle_intr();
13:    }
14:    ...
15:}

    如果没有sigprocmask(SIG_BLOCK, &new, old)这行代码阻塞信号,程序执行完7,8行之后,你投递INT,于是INT立即被处理,然后进入9行阻塞。
你本意是发送INT进入handle_intr()处理信号,然后pselect全然不知情的阻塞了。
    如果有sigprocmask(SIG_BLOCK, &new, old)这行代码,那么你要么在sigprocmask之前投递了INT,那么INT立即被处理,那么7,8行就可以被正确的处理。要么你在sigprocmask之后投递的INT,那么INT不会被处理,一直到pselect取消了阻塞,INT被处理。这个过程保证了你在处理一个信号结果的同时不会再有该信号被处理。




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值