免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 7079 | 回复: 9
打印 上一主题 下一主题

[算法] 多进程,多线程,单线程select复用的系统效率思考,望大家讨论! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-07-21 15:17 |只看该作者 |倒序浏览
最近一直在思考,是用多线程编程好,还是用单线程select复用的方法好。
评价的方法是能获得多少CPU时间。
思考如下:

假设系统运行后有N个进程。

这时需要完成一个任务。可以考虑再启用M个进程,一个进程M个线程,一个进程用select复用。

如果启用M个进程来完成服务。每个进程可以获得1/(M+N)的时间片。
如果启用一个进程,有M个线程。每个线程获得时间为1/(N+1) * 1/M 的时间片。一个进程的时间片还要被M个线程分用。
如果采用一个进程,用select进行复用。如果最多有M个sockfd被选中,那么每个sockfd获得的时间范围为
[1/(N+1)*1/M,1/(N+1)],最小为1/(N+1)*1/M,M个sockfd都被选中;最大为1/(N+1), 只有一个sockfd被选中。

这样看来,用select进行复用可以获得最大的时间片,多个进程居中,同时启用多个线程获得时间片最少。

不知这样的思考是否合适。

讨论的关键放在单线程select进行复用,同时启用多个线程吧。
多进程的系统开销太大。

只是想到了多进程,就写上去了。

小弟知道坛子里高人多,不过
最好是讨论单CPU的情况。
小弟没机会接触多CPU

实际中我的做法是启动一个主线程负责accept,另外的线程在没有连接到来时用条件变量阻塞。阻塞的时候不会消耗CPU时间。
有连接到来唤醒阻塞的线程处理,主线程和其他线程都使用select模型。

[ 本帖最后由 wlia 于 2009-7-22 09:47 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2009-07-21 15:27 |只看该作者
建议LZ再考虑一下进程上下文切换,线程切换的时间损耗。

这种问题,光用理论是不能说明问题的,还是要试验才行。

论坛徽章:
0
3 [报告]
发表于 2009-07-21 15:29 |只看该作者

回复 #2 foolishx 的帖子

谢谢,多进程不是初衷。马上改改原文。

论坛徽章:
0
4 [报告]
发表于 2009-07-21 15:30 |只看该作者
多核处理器,要注意使用多线程/进程+IO多路复用,这样才能将CPU的利用率提高到最大。

论坛徽章:
1
寅虎
日期:2014-11-30 21:25:54
5 [报告]
发表于 2009-07-21 15:36 |只看该作者
多cpu的还是多线程 线程个个数也有上限 超过了效率就低了
io时有阻塞(文件读写)的也应该多线程 不然单线程多路复用卡在那里整个程序就死了

论坛徽章:
0
6 [报告]
发表于 2009-07-21 18:14 |只看该作者
从简便的角度看,每个任务一个进程或线程是最好的,但是会有额外的调度损耗,如果实现得不讲究,惊群的成本很高。

从效率的角度看,应该依照CPU个数创建一个线程池,把N个任务分配给它们,可以最大程度降低调度成本。

总之,你要在实现效率和运行效率之间作出决断。

论坛徽章:
0
7 [报告]
发表于 2009-07-21 18:31 |只看该作者

回复 #1 wlia 的帖子

LZ对于时间片的想法是不是误入歧途了?

按我的理解,时间片不是这样单纯的有几个进程就均分给几个进程的。
非运行状态下的进程没有时间片(后台运行的大多数程序在大多数时间下都是非运行状态的);
运行状态下的进程决定其时间片的是优先级(静态+动态),以及一些动态加权;

如果想让处理进程占有足够多的时间片,那么就把它设成先进先出的实时进程好了,并且静态优先级尽量高;

论坛徽章:
224
2022北京冬奥会纪念版徽章
日期:2015-08-10 16:30:32操作系统版块每日发帖之星
日期:2016-02-18 06:20:00操作系统版块每日发帖之星
日期:2016-03-01 06:20:00操作系统版块每日发帖之星
日期:2016-03-02 06:20:0015-16赛季CBA联赛之上海
日期:2019-09-20 12:29:3219周年集字徽章-周
日期:2019-10-01 20:47:4815-16赛季CBA联赛之八一
日期:2020-10-23 18:30:5320周年集字徽章-20	
日期:2020-10-28 14:14:2615-16赛季CBA联赛之广夏
日期:2023-02-25 16:26:26CU十四周年纪念徽章
日期:2023-04-13 12:23:1015-16赛季CBA联赛之四川
日期:2023-07-25 16:53:45操作系统版块每日发帖之星
日期:2016-05-10 19:22:58
8 [报告]
发表于 2009-07-21 18:38 |只看该作者
选select

论坛徽章:
0
9 [报告]
发表于 2009-07-21 19:03 |只看该作者
LZ考虑的问题之前也考虑过,我现在采用epoll加多线程的模型。下面说说各种方式的优缺点。

优点:
多进程的好处是稳定性高,创建多个子进程来处理数据,一个子进程崩溃不会影响到其它进程,所以服务不会中断。
多线程的好处是写程序更加灵活,线程与其宿主进程共享堆栈,所以只要控制好同步,写起程序来和单线程没什么区别。另外线程的开销比进程小也是其优点,不过基本可以忽略不计。在*unx下,线程可以当做简化版本的进程。

缺点:
多进程,由于是不同的内存空间,所以要共享数据就很麻烦,我采用共享内存+用管道的方式控制,不过这样做增加了编程难度,很容易出错。而且业务逻辑基本都是由一个单独的进程实现,如果这个进程崩溃了那网络层还在跑也就没什么意义了,不幸的是业务逻辑是最容易出错的地方。
多线程,由于其使用宿主进程的堆栈,所以如果一个线程出错或锁死整个进程基本上就玩完了。

对比之下我选择了多线程模型,在相同的需求下多线程实现起来更简单清晰,不容易出错。而且就算出错,多进程的结果也和多线程一样,不会好太多。

LZ说的多进程上加多线程的方式,这个方式我也实现了一个原型,效果跟多进程和多线程一样,没有什么优势,只会增加出错几率而已。编程的时候要考虑一下硬件需求,现今的硬件及网络环境,多进程或多线程就足已满足要求了。

看到LS的提到惊群,顺便说两句。惊群现象不完全是坏的,当accept时引发惊群是可以接受的。因为连接是不可以丢弃的,必须让用户第一时间连接上服务器,所以需要由同时多个线程等待连接进,引起惊群现象也再所难免。当然普通的read/write操作引起惊群是不能接受的。

至于CPU利用率问题,理论上讲当工作的线程/进程数量为CPU个数*2+1时CPU利用率最高。这里CPU个数包含核心的个数,例如双核U就是2*2+1,四核U就是4*2+1。

[ 本帖最后由 kevin.c 于 2009-7-22 00:58 编辑 ]

论坛徽章:
0
10 [报告]
发表于 2009-07-22 09:41 |只看该作者

回复 #6 JohnBull 的帖子

惊群问题第一次听说,赶快GOOGLE。
其实我的做法是启动一个主线程负责accept,另外的线程在没有连接到来时用条件变量阻塞。阻塞的时候不会消耗CPU时间。
有连接到来唤醒阻塞的线程处理,主线程和其他线程都使用select模型。

[ 本帖最后由 wlia 于 2009-7-22 09:46 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP