Python多进程编程技术实例分析


Posted in Python onSeptember 16, 2014

本文以实例形式分析了Python多进程编程技术,有助于进一步Python程序设计技巧。分享给大家供大家参考。具体分析如下:

一般来说,由于Python的线程有些限制,例如多线程不能充分利用多核CPU等问题,因此在Python中我们更倾向使用多进程。但在做不阻塞的异步UI等场景,我们也会使用多线程。本篇文章主要探讨Python多进程的问题。

Python在2.6引入了多进程的机制,并提供了丰富的组件及api以方便编写并发应用。multiprocessing包的组件Process, Queue, Pipe, Lock等组件提供了与多线程类似的功能。使用这些组件,可以方便地编写多进程并发程序。

Process

Process的使用有点像java.lang.Thread,但Thread是线程。start方法用以启动某个进程。一个简单的示例:

from multiprocessing import Process
import os
import time
def sleeper(name, seconds):
  print "Process ID# %s" % (os.getpid())
  print "Parent Process ID# %s" % (os.getppid())
  print "%s will sleep for %s seconds" % (name, seconds)
  time.sleep(seconds)

if __name__ == "__main__":
  child_proc = Process(target=sleeper, args=('bob', 5))
  child_proc.start()
  print "in parent process after child process start"
  print "parent process abount to join child process"
  child_proc.join()
  print "in parent process after child process join"
  print "the parent's parent process: %s" % (os.getppid())

实例化一个Process必须要指定target和args。target是新的进程的入口方法,可以认为是main方法。args是该方法的参数列表。启动进程类似于启动Thread,必须要调用start方法。也可以继承Process,覆盖run方法,在run方法中实现该进程的逻辑。调用join方法会阻塞当前调用进程,直到被调用进程运行结束。
手工终止一个进程可以调用terminate方法,在UNIX系统中,该方法会发送SIGTERM信号量,而在windows系统中,会借助TerminateProcess方法。需要注意的是,exit处理逻辑并不会被执行,该进程的子进程不会被终止,他们只会变成孤儿进程。

Queue

Queue是多进程安全的队列,可以使用Queue实现多进程之间的数据传递。put方法用以插入数据到队列中,put方法还有两个可选参数:blocked和timeout。如果blocked为True(默认值),并且timeout为正值,该方法会阻塞timeout指定的时间,直到该队列有剩余的空间。如果超时,会抛出Queue.Full异常。如果blocked为False,但该Queue已满,会立即抛出Queue.Full异常。

get方法可以从队列读取并且删除一个元素。同样,get方法有两个可选参数:blocked和timeout。如果blocked为True(默认值),并且timeout为正值,那么在等待时间内没有取到任何元素,会抛出Queue.Empty异常。如果blocked为False,有两种情况存在,如果Queue有一个值可用,则立即返回该值,否则,如果队列为空,则立即抛出Queue.Empty异常。Queue的一段示例代码:

from multiprocessing import Process, Queue
def offer(queue):
  queue.put("Hello World")
def test(queue, num):
  queue.put("Hello World: " + str(num))
if __name__ == '__main__':
  q = Queue()
  p1 = Process(target=test, args=(q, 1))
  p1.start()
  p = Process(target=offer, args=(q,))
  p.start()
  p2 = Process(target=test, args=(q, 2))
  p2.start()
  p2 = Process(target=test, args=(q, 3))
  p2.start()
  print q.get()
  print q.get()
  print q.get()
  print q.get()
  print q.close()

输出:

Hello World: 1
Hello World
Hello World: 2
None

Pipes

Pipe方法返回(conn1, conn2)代表一个管道的两个端。Pipe方法有duplex参数,如果duplex参数为True(默认值),那么这个管道是全双工模式,也就是说conn1和conn2均可收发。duplex为False,conn1只负责接受消息,conn2只负责发送消息。

send和recv方法分别是发送和接受消息的方法。例如,在全双工模式下,可以调用conn1.send发送消息,conn1.recv接收消息。如果没有消息可接收,recv方法会一直阻塞。如果管道已经被关闭,那么recv方法会抛出EOFError。

from multiprocessing import Process, Pipe

def send(conn):
  conn.send("Hello World")
  conn.close()
if __name__ == '__main__':
  parent_conn, child_conn = Pipe()
  p = Process(target=send, args=(child_conn,))
  p.start()
  print parent_conn.recv()

同步

multiprocessing包提供了Condition, Event, Lock, RLock, Semaphore等组件可用于同步。下面是使用Lock的一个示例:

from multiprocessing import Process, Lock
def l(lock, num):
  lock.acquire() 
  print "Hello Num: %s" % (num)
  lock.release()
if __name__ == '__main__':
  lock = Lock()
for num in range(20):
  Process(target=l, args=(lock, num)).start()

总结

以上是Python multiprocessing库的简单介绍和实例,熟悉Java多线程开发的同学是不是觉得很熟悉,和java的Concurrency API很像,不过javaConcurrency是处理多线程的而已,我们可以直接按照以前Java多线程的经验用这些API。

感兴趣的朋友可以测试运行本文实例以加深理解。相信本文所述对大家Python程序设计的学习有一定的借鉴价值。

Python 相关文章推荐
python实现排序算法
Feb 14 Python
python的pdb调试命令的命令整理及实例
Jul 12 Python
Python内置函数 next的具体使用方法
Nov 24 Python
Python判断两个list是否是父子集关系的实例
May 04 Python
python pandas实现excel转为html格式的方法
Oct 23 Python
python3+PyQt5 数据库编程--增删改实例
Jun 17 Python
python实现批量修改服务器密码的方法
Aug 13 Python
使用python实现哈希表、字典、集合操作
Dec 22 Python
tensorflow使用指定gpu的方法
Feb 04 Python
python框架flask入门之路由及简单实现方法
Jun 07 Python
基于Python-Pycharm实现的猴子摘桃小游戏(源代码)
Feb 20 Python
Python使用tkinter实现小时钟效果
Feb 22 Python
Python专用方法与迭代机制实例分析
Sep 15 #Python
跟老齐学Python之有容乃大的list(3)
Sep 15 #Python
跟老齐学Python之有容乃大的list(2)
Sep 15 #Python
跟老齐学Python之有容乃大的list(1)
Sep 14 #Python
跟老齐学Python之一个免费的实验室
Sep 14 #Python
跟老齐学Python之从if开始语句的征程
Sep 14 #Python
跟老齐学Python之眼花缭乱的运算符
Sep 14 #Python
You might like
php中使用preg_replace函数匹配图片并加上链接的方法
2013/02/06 PHP
解析PHP函数array_flip()在重复数组元素删除中的作用
2013/06/27 PHP
一种JavaScript的设计模式
2006/11/22 Javascript
JS实多级联动下拉菜单类,简单实现省市区联动菜单!
2007/05/03 Javascript
纯js实现背景图片切换效果代码
2010/11/14 Javascript
jquery移除、绑定、触发元素事件使用示例详解
2014/04/10 Javascript
详解JavaScript中getFullYear()方法的使用
2015/06/10 Javascript
thinkphp实现无限分类(使用递归)
2015/12/19 Javascript
使用jquery.form.js实现图片上传的方法
2016/05/05 Javascript
浅谈js构造函数的方法与原型prototype
2016/07/04 Javascript
Highcharts+NodeJS搭建数据可视化平台示例
2017/01/01 NodeJs
jQuery模拟爆炸倒计时功能实例代码
2017/08/21 jQuery
js删除数组中的元素delete和splice的区别详解
2018/02/03 Javascript
微信小程序制作表格的方法
2019/02/14 Javascript
Vue CLI3中使用compass normalize的方法
2019/05/30 Javascript
vue使用echarts实现水平柱形图实例
2020/09/09 Javascript
python实现合并两个排序的链表
2019/03/03 Python
人工神经网络算法知识点总结
2019/06/11 Python
Python 生成一个从0到n个数字的列表4种方法小结
2019/11/28 Python
python随机生成库faker库api实例详解
2019/11/28 Python
python使用numpy实现直方图反向投影示例
2020/01/17 Python
Python 输出详细的异常信息(traceback)方式
2020/04/08 Python
Django表单提交后实现获取相同name的不同value值
2020/05/14 Python
Python xml、字典、json、类四种数据类型如何实现互相转换
2020/05/27 Python
Python hashlib和hmac模块使用方法解析
2020/12/08 Python
css3中新增的样式使用示例附效果图
2014/08/19 HTML / CSS
HTML5 新表单类型示例代码
2018/03/20 HTML / CSS
英国领先的运动营养品牌:Protein Dynamix
2018/01/02 全球购物
英国蛋糕装饰用品一站式商店:Craft Company
2019/03/18 全球购物
英国的潮牌鞋履服饰商店:size?
2019/03/26 全球购物
NYX Professional Makeup英国官网:美国平价专业彩妆品牌
2019/11/13 全球购物
Lookfantastic澳大利亚官网:英国知名美妆购物网站
2021/01/07 全球购物
初中生散播谣言检讨书
2014/11/17 职场文书
接待员岗位职责
2015/02/13 职场文书
2015年教师节活动总结
2015/03/20 职场文书
2015年度房地产工作总结
2015/04/09 职场文书