原理: 有一群狗在睡觉,你扔了一块肉,所有狗都去抢了,只有动作最快的狗抢到了,其余狗继续睡觉。
在socket中的影响
1, 多线程阻塞 accept, 当有一个连接到达时,所有线程均被唤醒,其中只有一个线程会获得连接,其余线程继续回复睡眠。
表面上看,就是一个线程会被唤醒,用户不可感知。--惊群
tcp/ip详解卷2, 366页
accept()
{
while(qlen==0)
tsleep
...
}
如果多线程accept, 则都在tsleep处挂起。当有一个连接时,所有线程的tsleep返回0. 最先运行的线程获得连接,其余线程由于qlen==0,继续tsleep
2,多线程阻塞select, 当有一个事件发生时,会唤醒所有线程,--select冲突
表面上看,就是所有线程都返回了,用户可感知------和accept不同,accept最终只有一个线程返回。
如果只有一个事件发生,那所有线程都返回了,一方面效率低下,一方面可能会对同一事件重复操作。
tcp/ip详解卷2, 428页
unix网络编程,658页
server: main.rar
client: main.rar
代码显示, 多线程select阻塞后,有事件发生,会唤醒所有线程,并且返回值相同。
///////////////////////////////////////////////////////////////////////////////////
iocp, epoll貌似没这方面问题。
据说新的操作系统,accept的问题已解决。
iocp没这问题。
MSDN: I/O Completion Ports:
A thread uses the GetQueuedCompletionStatus function to wait for a completion packet to be queued to the completion port, rather than waiting directly for the asynchronous I/O to complete. Threads that block their execution on a completion port are released in last-in-first-out (LIFO) order. This means that when a completion packet is queued to the completion port, the system releases the last thread to block its execution on the port.
This means that when a completion packet is queued to the completion port, the system releases the last thread to block its execution on the port.
epoll_wait好像内部是领导者追随者模式的,那也不该有问题。
阅读(5645) | 评论(0) | 转发(0) |