多个线程在单个套接字或管道上执行poll()或select()

wil*_*ilx 21 sockets multithreading posix sus

POSIX和其他标准对多线程在同一时间执行poll()select()调用单个套接字或管道句柄的情况有何看法?

如果有任何数据到达,只有一个等待线程被唤醒或所有等待线程被唤醒?

sub*_*sub 19

有趣的问题...我通读了当前的POSIX并没有找到具体的答案,即没有关于并发调用的规范.所以我会解释为什么我认为标准意味着所有人都会醒来.

在有关部分的文本select/ pselect是:

成功完成后,将PSELECT()或select()函数将修改的对象指向了readfds,writefds和errorfds参数指示哪些文件描述符准备好读,准备好写,或有挂起的错误条件,分别,[...]

然后

当对具有O_NONBLOCK clear的输入函数的调用不会阻塞时,该函数将成功传输数据时,应认为描述符已准备好进行读取.(该函数可能返回数据,结束文件的指示,或多于一个的指示它被阻塞,并且在每一种情况下的描述符应考虑准备用于读取其它错误.)

简而言之(仅限阅读案例),我们可以理解为:

select不阻止这意味着下一次调用输入函数O_NONBLOCK不会返回错误errno==EWOULDBLOCK.[请注意,"下一步"是我对上述内容的解释.

如果一个人承认这种解释,那么两个并发select调用都可以返回相同的FD作为可读.事实上,即使它们不是并发的,但是第一个线程调用select一些FD是可读的并且稍后例如,在两者之间read调用的第二个线程select可以将FD返回为第二个线程可读的.

现在问题"醒来"部分的相关部分是这样的:

如果所选描述符都没有为所请求的操作做好准备,则pselect()或select()函数将阻塞,直到至少一个请求的操作准备就绪,直到超时发生,或直到被信号中断为止.

在这里,上面的解释清楚地表明,同时等待的呼叫将全部返回.


stu*_*stu 5

由于这个问题,我才发现一个错误:我在同一套接字上选择了两个线程,并且当fd作为isset()返回时将调用accept。实际上,两个线程的选择又回来了,两个线程中的那个fd的fd isset()都返回了,两个线程都调用accept(),一个获胜,另一个块等待另一个连接进入。

因此,实际上select将在同一fd阻塞的所有线程中返回。

  • 如果您知道重力的作用,重力也就不足为奇了。但是牛顿感到惊讶。:-) (3认同)