Python的线程因为解释器锁的设计,所以不能充分利用CPU,只能通过进程来实现多核利用
性能考虑的话,底层还是不要用Py,进程切换效率太低,Py多做为脚本层的胶水语言
fork子进程
如果是linux上,可以使用linux的fork函数创建子进程
在python里通过os模块调用linux的fork,可以直接生成一个与当前进程执行完fork语句后的状态一致的拷贝子进程
import os
pid = os.fork()
if pid==0:
#0代表没有子进程,所以是子进程
print 'son'
else:
#父进程
print 'father'
创建独立子进程
windows下没有fork,但是multiprocessing模块的Process类提供了一个跨平台的多线程实现——通过传入方法对象和方法参数,构造进程对象,提供类似线程的start等方法
from multiprocessing import Process
def show(x):
print(x)
#如果是在windows下,需要使用下面判断,确保解释器完成了主进程创建引导后再创建子进程
if __name__=='__main__':
#创建线程必须在
p = Process(target=show,args=('YYT',))
p.start()
#join保证等到p进程执行结束才继续往下执行(避免主进程结束,子进程被关闭)
p.join()
使用进程池
multiprocessing模块的Pool类提供创建进程池
from multiprocessing import Pool
import time, random
def show(i):
time.sleep(random.random() * 3)
print(i)
if __name__=='__main__':
p = Pool()
for i in range(5):
p.apply_async(show, args=(i,))
time.sleep(5)
print("apply done...")
p.close()
#进程池close了才能使用join
p.join()
#join会阻塞到进程池全部进程执行完
print("All done.")
进程间通信
multiprocessing模块的Queue类,提供进程安全的阻塞队列
from multiprocessing import Process, Queue
import time, random
def PutQueue(q):
time.sleep(random.random())
q.put('yyt')
def GetQueue(q):
while True:
value = q.get()
print ('Get %s.' % value)
if __name__=='__main__':
q = Queue()
pq = Process(target=PutQueue, args=(q,))
gq = Process(target=GetQueue, args=(q,))
gq.start()
pq.start()
pq.join()
#强行终止GetQueue
gq.terminate()
更多文章,请搜索公众号歪歪梯Club