Python的线程因为解释器锁的设计,所以不能充分利用CPU,只能通过进程来实现多核利用 性能考虑的话,底层还是不要用Py,进程切换效率太低,Py多做为脚本层的胶水语言
fork子进程
如果是linux上,可以使用linux的fork函数创建子进程 在python里通过os模块调用linux的fork,可以直接生成一个与当前进程执行完fork语句后的状态一致的拷贝子进程
代码语言:javascript复制import ospid = os.fork()if pid==0: #0代表没有子进程,所以是子进程 print 'son'else: #父进程 print 'father'
创建独立子进程
windows下没有fork,但是multiprocessing模块的Process类提供了一个跨平台的多线程实现——通过传入方法对象和方法参数,构造进程对象,提供类似线程的start等方法
代码语言:javascript复制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类提供创建进程池
代码语言:javascript复制from multiprocessing import Poolimport 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类,提供进程安全的阻塞队列
代码语言:javascript复制from multiprocessing import Process, Queueimport 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()