Python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程。Python提供了非常好用的多进程包multiprocessing,只需要定义一个函数,Python会完成其他所有事情。借助这个包,可以轻松完成从单进程到并发执行的转换。multiprocessing支持子进程、通信和共享数据、执行不同形式的同步,提供了Process、Queue、Pipe、Lock等组件。
引例:
如之前创建多进程的例子
# -*- coding:utf-8 -*-from multiprocessing import Process,Poolimport os,timedef run_proc(name): ##定义一个函数用于进程调用 for i in range(5): time.sleep(0.2) #休眠0.2秒 print 'Run child process %s (%s)' % (name, os.getpid())#执行一次该函数共需1秒的时间if __name__ =='__main__': #执行主进程 print 'Run the main process (%s).' % (os.getpid()) mainStart = time.time() #记录主进程开始的时间 p = Pool(8) #开辟进程池 for i in range(16): #开辟14个进程 p.apply_async(run_proc,args=('Process'+str(i),))#每个进程都调用run_proc函数, #args表示给该函数传递的参数。 print 'Waiting for all subprocesses done ...' p.close() #关闭进程池 p.join() #等待开辟的所有进程执行完后,主进程才继续往下执行 print 'All subprocesses done' mainEnd = time.time() #记录主进程结束时间 print 'All process ran %0.2f seconds.' % (mainEnd-mainStart) #主进程执行时间
运行结果:
Run the main process (36652). Waiting for all subprocesses done … Run child process Process0 (36708)Run child process Process1 (36748)Run child process Process3 (36736) Run child process Process2 (36716) Run child process Process4 (36768)
如第3行的输出,偶尔会出现这样不如意的输入格式,为什么呢?
原因是多个进程争用打印输出资源的结果。前一个进程为来得急输出换行符,该资源就切换给了另一个进程使用,致使两个进程输出在同一行上,而前一个进程的换行符在下一次获得资源时才打印输出。
Lock
为了避免这种情况,需在进程进入临界区(使进程进入临界资源的那段代码,称为临界区)时加锁。
可以向如下这样添加锁后看看执行效果:
# -*- coding:utf-8 -*-lock = Lock() #申明一个全局的lock对象def run_proc(name): global lock #引用全局锁 for i in range(5): time.sleep(0.2) lock.acquire() #申请锁 print 'Run child process %s (%s)' % (name, os.getpid()) lock.release() #释放锁
Semaphore
Semaphore为信号量机制。当共享的资源拥有多个时,可用Semaphore来实现进程同步。其用法和Lock差不多,s = Semaphore(N),每执行一次s.acquire(),该资源的可用个数将减少1,当资源个数已为0时,就进入阻塞;每执行一次s.release(),占用的资源被释放,该资源的可用个数增加1。
新闻热点
疑难解答