锁定老帖子 主题:2.7相比2.4的多线程性能提高了..
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (2)
|
|
---|---|
作者 | 正文 |
发表时间:2012-03-02
最后修改:2012-03-02
昨天在2.7下换回多线程,发现一样的性能... multiprocessing岂不意义不大了?不过我觉得可能是我在进程间共用了一个Queue所致,如果进程间不通信,会不会好点? 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2012-03-02
我错了,我自问自答..忽然发觉另一个处理日志的程序,用进程比线程快了近一倍。
差不多可以确定,资源争用影响性能。 |
|
返回顶楼 | |
发表时间:2012-03-02
操作系统对于进程的调度,比线程库对于线程的调度,要可靠、准确得多。
|
|
返回顶楼 | |
发表时间:2012-03-11
应该不是说windows吧
|
|
返回顶楼 | |
发表时间:2012-03-12
multiprocessing 在windows下相当慢。和os的机制有关。
在*nix下相当快,基本上可以替代thread |
|
返回顶楼 | |
发表时间:2012-03-13
我记得是这样的:
Python中多线程一定是按照时间片划分的方式工作,因为它有个全局锁(叫什么我忘了),这个锁在任何时候都只能有一个线程获得。这意味着即使你有多核CPU,使用多线程方式你的程序也利用不了100%的CPU。 多线程方式: import threading def forevery() : while True: pass t1 = threading.Thread(target=forevery) t1.setDaemon(True) t1.start() forevery() print 'go on...' 我的机器是Ubuntu 双核。CPU撑不满。 但换成多进程方式就可以: import multiprocessing def forevery() : while True: pass p1 = multiprocessing.Process(target=forevery) p1.start() forevery() print 'go on...' 这个程序可以沾满两个CPU --------------------------------------- 这说明至少在linux平台上,python的多进程方式比多线程方式更能利用CPU多核优势。 那剩下的就是看你的应用类型了,如果你的应用是个CPU bunding类型,而不是IO bunding类型,那么多进程比较适合。反或来,如果你的应用的是IO bunding类型,例如Web服务等等,那么多进程可能就没什么优势了,反正阻塞在IO上面,CPU再多也没用,那还不如换多线程,对操作系统来说也更轻量级一些。 仅个人认识,不要轻信 |
|
返回顶楼 | |
发表时间:2012-03-13
最后修改:2012-03-13
感谢各位回复,是SUSE Linux上的,是一个Socket Server,收消息,发响应,存消息,然后再构造请求发回去。
这几天在做另一个桩,处理一个很偏门的协议,叫UCP,处理协议细节很麻烦。其中一个细节是,往对端发的请求是非阻塞式的,可以一股脑儿拽过去N多请求,响应你对端可以慢慢回,但是有个限制:最多可以允许有100条请求没有收到响应。所以在发送请求时有下面这段: if msgQueue.qsize()>0 and noResReportCount<100: print msgQueue.qsize() buffer=msgQueue.get().split(':') theSocket.sendall(encodeReport(buffer)) //发送请求给对端 noResReportCount+=1 但是忽然发现,这段代码在一个线程的target函数里,会有并发问题:如果有10个线程同时判断进入条件为真,都进去了,那么最后noResReportCount会涨到109,破坏了“100条规则”... 不想加锁,于是改成了: if msgQueue.qsize()>0 and noResReportCount<100: noResReportCount+=1 #in order that concurrent access if noResReportCount>100: noResReportCount-=1 break //外面有while循环,如果破坏了100条规则就直接退出 print msgQueue.qsize() buffer=msgQueue.get().split(':') theSocket.sendall(encodeReport(buffer))线程这个东西没经验不能用啊,开发们估计这方面积累较多吧,测试伤不起... |
|
返回顶楼 | |
发表时间:2012-03-14
最后修改:2012-03-14
if msgQueue.qsize()>0 and noResReportCount<100: noResReportCount+=1 #in order that concurrent access if noResReportCount>100: noResReportCount-=1 break //外面有while循环,如果破坏了100条规则就直接退出 print msgQueue.qsize() buffer=msgQueue.get().split(':') theSocket.sendall(encodeReport(buffer)) 恐怕还是不行,假设当前noResReportCount = 90,10条线程都到执行 noResReportCount+=1的位置,10条轮换这执行noResReportCount+=1,结果 noResReportCount = 100,再往下进行一起轮换执行 if noResReportCount>100,结果都会命中,再往下去轮换执行noResReportCount-=1,减到90(这时已经晚了),最后一起退出。也就是说有可能达不到原来要求的最大限。100 - 线程数 = 你的消息条数,如果的线程数很大,就有可能一条都发不出去。 |
|
返回顶楼 | |
发表时间:2012-03-14
一定要用多线程、多进程吗?看看Twisted(对应于Ruby:EventMachine,JavaScript:Node.js)。
|
|
返回顶楼 | |
发表时间:2012-03-15
shenyu 写道 if msgQueue.qsize()>0 and noResReportCount<100: noResReportCount+=1 #in order that concurrent access if noResReportCount>100: noResReportCount-=1 break //外面有while循环,如果破坏了100条规则就直接退出 print msgQueue.qsize() buffer=msgQueue.get().split(':') theSocket.sendall(encodeReport(buffer)) 恐怕还是不行,假设当前noResReportCount = 90,10条线程都到执行 noResReportCount+=1的位置,10条轮换这执行noResReportCount+=1,结果 noResReportCount = 100,再往下进行一起轮换执行 if noResReportCount>100,结果都会命中,再往下去轮换执行noResReportCount-=1,减到90(这时已经晚了),最后一起退出。也就是说有可能达不到原来要求的最大限。100 - 线程数 = 你的消息条数,如果的线程数很大,就有可能一条都发不出去。 也是啊 是不是只有用锁把 if noResReportCount>100: noResReportCount-=1 break 锁住了? |
|
返回顶楼 | |