免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: 思一克

惊群(thundering herd)问题在linux上可能是莫须有的问题 [复制链接]

论坛徽章:
0
发表于 2007-06-08 12:40 |显示全部楼层
通常我么
poll+read的时候都没有注意,如果是多个进程,那么我们很可能需要在poll返回时非阻塞的读,否则,即使poll返回了,也可能导致后果很严重的阻塞

论坛徽章:
0
发表于 2007-06-08 12:42 |显示全部楼层
to converse,

我实验select了,一个进程fork 多个CHILD读阻塞在read pipe. 和用select阻塞在select
main进程写数据。

结果是一有数据,所有进程被唤醒。

我想这是KERNEL故意为之。因为KERNEL不知道用户的心思。有数据了,数据很可能是要分给多个读者的。
KERNEL不能假设数据是给一个读者的。因此要WAKEUP所有的。

select是如此, read pipe也是如此。

但accept完全不同,kernel知道仅仅一个可以accept. 不会有2个同时accept一个进入连接。


原帖由 flw2 于 2007-6-8 12:14 发表
就算唤醒n个进程,如果得不到资源,那么也到不了user态了,马上又阻塞的kernel态

[ 本帖最后由 思一克 于 2007-6-8 12:43 编辑 ]

论坛徽章:
0
发表于 2007-06-08 12:57 |显示全部楼层
版主说的其实是一个waker函数决定的。
阻塞在某个地方的代码处,那么对应的waker也知道该怎么去唤醒等待队列。原则就是是不是排他的。它自己知道
对于poll,select,就算给一个进程读,也有可能本来有100字节,可是每个进程只要40个字节,那么肯定要唤醒,内核waker并不知道进程将来的read要读多少字节。即使只有3字节,有100个进程在等也要唤醒,它不会去检查

论坛徽章:
0
发表于 2007-06-08 13:04 |显示全部楼层
对。所以read, select ( 应该也包含poll), 都是要唤醒所有的等待进程。因为可能要分发数据。
accept没有分发数据问题,是唯一的,所以唤醒一个。

还有一个误区, 认为唤醒后立即检查如果没有资源在KERNEL中立即睡下,不返回用户空间。
我看了sys_poll, sys_select等的代码,没有这中机制(可能)。醒了没有几条就返回USER空间了。

所以在用户空间加printf测试应该没有问题,至少对于,select, poll, read等是这样。

论坛徽章:
0
发表于 2007-06-08 13:07 |显示全部楼层
原帖由 flw2 于 2007-6-8 12:40 发表
通常我么
poll+read的时候都没有注意,如果是多个进程,那么我们很可能需要在poll返回时非阻塞的读,否则,即使poll返回了,也可能导致后果很严重的阻塞

阻塞式read在任何時候都可能被阻塞,除非真的要讀完數據,否則不能用blocking read。

论坛徽章:
0
发表于 2007-06-08 13:10 |显示全部楼层
根据研究结果,多个进程直接accept一个sock是没有问题的好程序。
但不好的程序是(如果能这样编的话)

r = select(........);  //或 poll(....)
if(r) {
    fd1 = accept(.........):
}

这样有惊群问题,但不是KERNEL的问题,而是一个不好的用户程序造成的。

还有这样也是不好的:
lock(...);
accept(....);
unlock(...);

程序慢了,无谓的牺牲。

[ 本帖最后由 思一克 于 2007-6-8 13:11 编辑 ]

论坛徽章:
0
发表于 2007-06-08 13:40 |显示全部楼层
不知道为啥,看到"惊群"这个名字让我有点发慌.....

论坛徽章:
1
IT运维版块每日发帖之星
日期:2016-05-28 06:20:00
发表于 2007-06-08 14:32 |显示全部楼层
原帖由 baohuaihuai 于 2007-6-8 13:40 发表
不知道为啥,看到"惊群"这个名字让我有点发慌.....


万马奔腾

其实就是一个资源被释放了,等待该资源的一堆线程被唤醒,有个幸运儿获得,其他不幸的家伙一个个回去睡觉,如此反复!

论坛徽章:
0
发表于 2007-06-08 15:04 |显示全部楼层
我这个帖子说的不完全对。

对listen()后的描述符进行select, poll 好象不会“惊群”,不会象对文件描述符或accepted()后的sock那样.

listen的描述符特别处理,和accept()的情况一样。

没有时间精确测试,有兴趣的可以实验。


原帖由 思一克 于 2007-6-8 13:10 发表
根据研究结果,多个进程直接accept一个sock是没有问题的好程序。
但不好的程序是(如果能这样编的话)

r = select(........);  //或 poll(....)
if(r) {
    fd1 = accept(.........):
}

这样有惊群 ...

论坛徽章:
0
发表于 2007-06-08 15:18 |显示全部楼层
如果只有 2 个进程来 accept 1 个 socket, 那么是否能够认为在大量的客户端 connect 后, 着两个进程 accepted 的 socket 的个数相当?

我比较关心这个问题, 呵呵
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

DTCC2020中国数据库技术大会 限时9.5折

【架构革新 高效可控】2020年8月17日~19日第十一届中国数据库技术大会将在北京隆重召开。

大会设置2大主会场,20+技术专场,将邀请超百位行业专家,重点围绕数据架构、AI与大数据、传统企业数据库实践和国产开源数据库等内容展开分享和探讨,为广大数据领域从业人士提供一场年度盛会和交流平台。

http://dtcc.it168.com


大会官网>>
  

北京盛拓优讯信息技术有限公司. 版权所有 16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122
中国互联网协会会员  联系我们:huangweiwei@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP