+ -
当前位置:首页 → 问答吧 → pselect最后一个参数怎么用

pselect最后一个参数怎么用

时间:2011-12-02

来源:互联网

C/C++ code

 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){
10if (errno = EINTR){
11if (intr_flag)
12:            handle_intr();
13:    }
14:    ...
15:}


看得懂这段简短的代码吧,我想问一下sigprocmask最主要是做什么的,然后pselect的最后一个参数是空集是否执行pselect时屏蔽所有的信号?这里用pselect代替select的原因是如果SIGINT在第7到第9行之间发生的话就会丢失了,这里我就不明白pselect可以防止信号丢失呢?

作者: xiaofen8   发布时间: 2011-12-02

这和:

pthread_mutex_lock();
pthread_cond_wait()
pthread_mutex_unlock();

原理是一样的。

必须保证我们检查变量的时候,变量不会被信号处理函数改动,所以procmask阻塞INT信号,检查完了就可以pselect的最后一个参数取消对所有信号的阻塞,如果在procmask之后投递了INT,此时pselect会被中断,并且原子的阻塞INT并且返回,由于是errno==EINTR,所以检查变量,做处理。

举个例子,如果你的pselect没有超时,也没有sigprocmask阻塞信号。 

程序执行完7,8行之后,你投递INT,于是INT立即被处理,然后进入9行阻塞。

你本意是发送INT中止pselect,然后pselect全然不知情的阻塞了。

如果你promask了,那么你要么在promask之前投递了INT,那么INT立即被处理,那么7,8行就可以被正确的处理。

如果是你promask之后投递的INT,那么INT不会被处理,一直到pselect取消了阻塞,INT被处理,并且中断了pselect,然后被handle_intr处理。

并且这个过程保证了你在处理一个信号结果的同时不会再有该信号被处理。

作者: qq120848369   发布时间: 2011-12-02