7.6【多线程与多进程】使用多进程

文章介绍了Python中的全局解释器锁(GIL)如何限制了多线程在CPU密集型任务中的并行执行,推荐使用多进程模型通过multiprocessing模块来解决这个问题。文中通过示例展示了如何创建和管理进程,以及进程间通信的方法,如Queue和Pipe。最后,文章通过对比多线程和多进程处理特定计算任务的时间,强调了多进程在CPU密集型任务中的优势。
摘要由CSDN通过智能技术生成
由于python中全局解释器(GIL)的存在,在任意时刻只允许一个线程在解释器中运行。因此python的多线程不适合处理cpu密集型任务。想要处理cpu密集型任务,可以使用多进程模型
GIL是一个线程锁,可以锁住同一个进程内的多个线程,但对于不同进程中的线程,没作用;
所以,不同进程下的线程可以同时工作
#
使用标准库中multiprocessing.Process,它可以启动子进程执行任务。操作接口,进程间通信,进程间同步等都与Threading.Thread类似

from multiprocessing import Process
def f(s): print s
p = Process(target=f, args=('hello', ))
p.start()
# hello
p.join()

x = 1
def f():
	global x
	x = 5
f()
x # 5
x = 1
p = Process(target=f)
p.start()
x # 1 ;	说明主进程和子进程看到的x非同一个;多个进程之间,它们的虚拟地址空间是独立的
进程之间无法访问彼此的空间,互相通信方法:
from multiprocessing import Queue, Pipe
# import Queue;这俩非同一个对象,接口几乎一致;上面Queue使用在进程环境下
q = Queue()
q.put(1)
q.get() # 1
def f(q):
	print 'start'
	print q.get()
	print 'end'
Process(target=f, args=(q,)).start()
# start	;	阻塞在q.get(),等待传入
q.put(100)
# 100 
# end
c1,c2 = Pipe() # 会创建一个双向的管道
c1.send('abc')
c2.recv() # 'abc'
c2.send('xyz') # c2写入,只能从c1输出
c1.recv() # 'xyz'

def f(c):
	c.send(c.recv() * 2)
c1, c2 = Pipe()
Process(target=f, args=(c2,)).start()
c1.send(55)
c1.recv() # 110

#多线程,多进程;执行一个cpu密集型任务,对比运行时间
from threading import Thread
from multiprocessing import Process
def isArmstrong(n): # 判断某数是否为水仙花数
	a, t = [], n
	while t>0:
		a.append(t % 10)
		t /= 10
	k = len(a)
	return sum(x ** k for x in a) == n
def findArmstrong(a, b):# 特定范围查到全部
	print a, b
	res = [k for k in xrange(a, b) if isArmstrong(k)]
	print '%s ~ %s: %s' % (a, b, res)
def findByThread(*argslist): # 使用多线程调用查找
	workers = []
	for args in argslist:
		worker = Thread(target=findArmstrong, args=args)
		worker.append(worker)
		worker.start()
	for worker in workers:
		worker.join()
def findByProcess(*argslist):# 使用多进程调用查找
	workers = []
	for args in argslist:
		worker = Process(target=findArmstrong, args=args)
		workers.append(worker)
		worker.start()
	for worker in workers:
		worker.join()

if __name__ == '__main__':
	import time
	start = time.time()
	findByProcess((20000000,25000000), (25000000, 30000000)) # 两个范围两个进程,两个cpu使用率100%,15s
	#findByThread((20000000,25000000), (25000000, 30000000))# 两个线程,两个cpu没达到100%,系统使用时间变长,说明在来回调度,40s
	print time.time() - start
# linux下top命令,观察cpu使用情况
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值