python 多进程使用的一个假象
来源:互联网 发布:众筹平台数据统计 编辑:程序博客网 时间:2024/05/16 03:41
参考网站:http://blog.csdn.net/chobit_s/article/details/7083369
http://www.cnblogs.com/cloudaice/archive/2012/01/26/python_thread03.html
python-cn(华蟒用户组,CPyUG 邮件列表)上: 关于 python 多线程是否能用到多核的问题 相关讨论
本机环境: 2核CPU, linux 2.6, python 2.6.2
在python上开启多个线程,由于GIL的存在,每个单独线程都会在竞争到GIL后才
运行,这样就干预OS内部的进程(线程)调度,结果在多核CPU上:
python的多线程实际是串行执行的,并不会同一时间多个线程分布在多个CPU上运行。
但是这里有个有趣的现象: python开启两个死循环的线程,在我的2核机器上会有如下
CPU使用情况,每个CPU都维持在50%左右的使用率(见下图).
当然不是,在GIL存在的python上,多线程应该是不可能并行的。
这里其实有个小细节隐藏在linux的进程调度系统内,当python多线程切换时候,linux
调度子系统会兼顾多核的负载情况,linux会把多个线程平均分布在多核上跑,这样不
会导致单个核负载过盛。但是这个并不会让python多线程在多核上并行。
大致CPU使用应该这样:
cpu0: .. pythread0 _________ pythread0 _________ ..
cpu1: .. _________ pythread1 _________ pythread1 ..
('___'表示cpu空闲,这样统计下来每个核使用情况在50%左右)
如果python多线程真能在多核上并行,那么这里每个CPU使用率都应该接近100%.
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
昨天晚上在寝室写python多线程的时候,用了几个测试的程序,分别是递归方法求斐波那契数的值。分别采用单线程一个一个执行的方法和采用多线程调用的方法。观察所用的时间基本上差不多的。
然后我在每个函数内部加入sleep()函数以后,分别让它们睡零点几秒钟。这样一来,明显多线程执行所用的时间要少很多。
这时我突然好奇,想看看在用python多线程执行的时候,是否可以利用CPU多个核心呢?我的笔记本是i3处理器,双核,4线程(我至今不知道这里所指的4线程具体是什么意思,之前和老师交流过,猜测可能是在硬件上做了像我们软件执行的时候的躲进程这样类似的东西,但是不确定),反正在我的系统下的系统监视器里面可以看到有4个核的利用率频线。我就观察这种曲线的变化方式:当我每一个都是单线程地运行的时候。显示的画面中有一个CPU爆满;但是在多线程运行的时候,是每一个利用一些。
下面是系统监视器显示情况:
这是运行时间对比:
显然多线程运行的时候时间反而长了很多,虽然有上下文切换的时间损耗,但是若是能够利用多核的话也不至于那么慢,另外由系统监视器可以看出多线程的时候也没有把各个核利用率达到很高的一个水平。所以当时推断python的多线程并没有很多的利用多核CPU,其实之前也有听说过python对于多核CPU支持是个缺陷,现在是有真的体会,但是我只是凭自己的小实验,也不能有很打保证啊,也只是猜测,后来翻了一下《python参考手册》发现有这么一句话,看来是真的证实了我自己的猜想啊!!!
尽管是很低级的问题,但是对于初学的我来说,还是有很大的喜悦的。
下面是实验的代码:
fab.py:
1 # -*- coding: utf-8 -*- 2 from myThread import MyThread 3 from time import ctime 4 from time import sleep 5 import sys 6 7 def fib(x): 8 # sleep(0.005) 9 if x<2:return 110 return (fib(x-2) + fib(x-1))11 12 def fac(x):13 # sleep(0.05)14 if x<2:return 115 return (fac(x-2)+fac(x-1))16 17 def sum(x):18 # sleep(0.05)19 if x<2:return 120 return (sum(x-2)+sum(x-1))21 22 funcs = [fib,fac,sum]23 n = 3524 25 def main():26 nfuncs = range(len(funcs))27 sys.stdout.write('***SINGLE THREAD\n')28 for i in nfuncs:29 sys.stdout.write('starting %s at: %s\n' %(funcs[i].__name__,ctime()))30 print funcs[i](n)31 sys.stdout.write("%s finished at: %s\n"% (funcs[i].__name__,ctime()))32 sys.stdout.write('\n***MULTIPLE THREADS\n')33 34 threads = []35 36 for i in nfuncs:37 t = MyThread(funcs[i],(n,),funcs[i].__name__)38 threads.append(t)39 40 for i in nfuncs:41 threads[i].start()42 43 for i in nfuncs:44 threads[i].join()45 print threads[i].getResult()46 47 sys.stdout.write('all done\n')48 49 if __name__ == '__main__':50 main()
myThread.py:
1 import threading 2 from time import ctime 3 import sys 4 5 class MyThread(threading.Thread): 6 def __init__(self,func,args,name=''): 7 threading.Thread.__init__(self) 8 self.name = name 9 self.func = func10 self.args = args11 12 def getResult(self):13 return self.res14 15 def run(self):16 sys.stdout.write("starting %s at: %s\n" % (self.name,ctime()))17 self.res = apply(self.func,self.args)18 sys.stdout.write("%s finished at: %s\n" % (self.name,ctime()))
- python 多进程使用的一个假象
- 多核CPU上python多线程并行的一个假象
- 多核CPU上python多线程并行的一个假象
- 多核CPU上python多线程并行的一个假象
- 使用python的os.fork()为一个主进程生成多个子进程
- 诡异的假象
- 假象
- Python的多进程锁的使用
- python多进程multiprocessing的简单使用
- 之前用的一个多进程python爬虫
- 数据中存在的假象
- python中进程的使用
- python 进程池的使用
- python进程池的使用
- python 一个小的进程监控程序
- 使用 Python 实现多进程
- 使用 Python 实现多进程
- 使用 Python 实现多进程
- 泛型算法和迭代器适配器对整数排序
- 熊猫烧香
- ubuntu设置网络
- linux内核定时器
- 4.1 iOS开发视频教程—NSNumber数字的使用
- python 多进程使用的一个假象
- 从事前端开发必须要了解的CSS原理
- 单链表的基本操作
- Sicily1001 Alphacode
- 微软面试题:求整数随机数构成的数组中找到长度大于=3的最长的等差数列
- LINUX c++线程池框架
- 别的电脑上的ISE工程放到本电脑上后使用ModelSim仿真时出错的解决办法
- 使用boolalpha操作子
- verilog系统任务对文件的读写操作