python 之进程篇
多线程给我们的感觉
1.因为GIL的存在,一个进程的多线程同一时刻只能进去一个,感觉是假的并发
2.只适合I/O密集型的任务
3.针对计算密集型,就挂了(变成串行了)
在python中想要充分利用多核cpu的优势,就可用多进程这个技术---multiprocessing
multiprocessing是多进程的一个管理包。包含 Process、Queue、Pipe、Lock等组件。与thread类似
该Process对象与Thread对象的用法相同,也有start(), run(), join()的方法。此外multiprocessing包中也有Lock/Event/Semaphore/Condition类 (这些对象可以像多线程那样,通过参数传递给各个进程),用以同步进程,其用法与threading包中的同名类一致。所以,multiprocessing的很大一部份与threading使用同一套API,只不过换到了多进程的情境。
但在使用这些共享API的时候,我们要注意以下几点:
- 在UNIX平台上,当某个进程终结之后,该进程需要被其父进程调用wait,否则进程成为僵尸进程(Zombie)。所以,有必要对每个Process对象调用join()方法 (实际上等同于wait)。对于多线程来说,由于只有一个进程,所以不存在此必要性。
- multiprocessing提供了threading包中没有的IPC(比如Pipe和Queue),效率上更高。应优先考虑Pipe和Queue,避免使用Lock/Event/Semaphore/Condition等同步方式 (因为它们占据的不是用户进程的资源)。
- 多进程应该避免共享资源。在多线程中,我们可以比较容易地共享资源,比如使用全局变量或者传递参数。在多进程情况下,由于每个进程有自己独立的内存空间,以上方法并不合适。此时我们可以通过共享内存和Manager的方法来共享资源。但这样做提高了程序的复杂度,并因为同步的需要而降低了程序的效率。
简单的例子:
from multiprocessing import Process
import os
def info(name):
print(name)
print(os.getppid())#在主进程运行的是的是这个是pychar的pid
print(os.getpid()) if __name__ == "__main__":
info("main")
p=Process(target=info,args=("bob",))
p.start()
p.join()
进程之间通讯
1. Queue() 注意这个不同于进程queue。 每个进程之间使用pickle序列化实现
2. Pipe()
queue代码:注意q要当参数 传递给函数,不然无法使用。因为进程之间数据默认不共享的。
from multiprocessing import Process, Queue def f(q,n):
q.put([42, n, 'hello']) if __name__ == '__main__':
q = Queue()
p_list=[]
for i in range(3):
p = Process(target=f, args=(q,i))
p_list.append(p)
p.start()
print(q.get())
print(q.get())
print(q.get())
for i in p_list:
i.join()
Pipe代码
from multiprocessing import Process, Pipe def f(conn):
conn.send([42, None, 'hello'])
conn.close() if __name__ == '__main__':
parent_conn, child_conn = Pipe()
p = Process(target=f, args=(child_conn,))
p.start()
print(parent_conn.recv()) # prints "[42, None, 'hello']"
p.join()
进程之间数据共享:Manager组件
from multiprocessing import Process, Manager def f(d, l,n):
d[n] = ''
d[''] = 2
d[0.25] = None
l.append(n)
print(l) if __name__ == '__main__':
with Manager() as manager:
d = manager.dict() l = manager.list(range(5))
p_list = []
for i in range(10):
p = Process(target=f, args=(d, l,i))
p.start()
p_list.append(p)
for res in p_list:
res.join() print(d)
print(l)
这里存在一个问题:数据共享 是不是要加锁
进程之间的数据同步LOCK:
用法与线程的一样:主要是为了防止进程抢占屏幕输出,避免输出错乱
from multiprocessing import Process, Lock def f(l, i):
l.acquire()
try:
print('hello world', i)
finally:
l.release() if __name__ == '__main__':
lock = Lock() for num in range(10):
Process(target=f, args=(lock, num)).start()
进程池:
- pool.apply
- pool.apply_async
from multiprocessing import Pool
import os,time
def Foo(i):
time.sleep(2)
print("子进程",i,os.getpid())
def Bar(arg):
print("Exec done",arg,os.getpid())
if __name__=="__main__":
pool = Pool(3) #已经启动了10个进程,但是同一时刻只能有3个进程执行
for i in range(10):
#pool.apply(func=Foo,args=(i,)) #串行效果
#pool.apply_async(func=Foo,args=(i,))#异步方法,为了显示效果,必须加上,join。
pool.apply_async(func=Foo, args=(i,),callback=Bar) #异步使用回调函数,但是这个回调是在主进程中执行的,列如:在数据库连接的时候,如果在子进程连接,每个都要打开新的,不好
pool.close()
pool.join()#join之前,必须加上close,注意:close在前。
python 之进程篇的更多相关文章
- Python 踩坑之旅进程篇其三pgid是个什么鬼 (子进程\子孙进程无法kill 退出的解法)
目录 1.1 踩坑案例 1.2 填坑解法 1.3 坑位分析 1.4.1 技术关键字 下期坑位预告 代码示例支持 平台: Centos 6.3 Python: 2.7.14 Github: https: ...
- [代码修订版] Python 踩坑之旅 [进程篇其四] 踩透 uid euid suid gid egid sgid的坑坑洼洼
目录 1.1 踩坑案例 1.2 填坑解法 1.3 坑位分析 1.4 技术关键字 1.5 坑后思考 下期坑位预告 代码示例支持 平台: Centos 6.3 Python: 2.7.14 代码示例: 公 ...
- Python 踩坑之旅进程篇其四一次性踩透 uid euid suid gid egid sgid的坑坑洼洼
目录 1.1 踩坑案例 1.2 填坑解法 1.3 坑位分析 1.4 技术关键字 1.5 坑后思考 下期坑位预告 代码示例支持 平台: Centos 6.3 Python: 2.7.14 代码示例: 菜 ...
- Python【第一篇】基础介绍
一.本节主要内容 Python介绍 发展史 Python 2 or 3? 安装 Hello World程序 变量 用户输入 模块初识 .pyc文件 数据类型初识 数据运算 表达式if ...else语 ...
- Python3 与 C# 并发编程之~ 进程篇
上次说了很多Linux下进程相关知识,这边不再复述,下面来说说Python的并发编程,如有错误欢迎提出- 如果遇到听不懂的可以看上一次的文章:https://www.cnblogs.com/dot ...
- 【Python】第一篇:python基础_1
本篇内容 Python介绍 安装 第一个程序(hello,world) 变量 用户输入(input) 数据类型 数据运算 if判断 break和continue的区别 while 循环 一. Pyth ...
- Python进阶----进程之间通信(互斥锁,队列(参数:timeout和block),), ***生产消费者模型
Python进阶----进程之间通信(互斥锁,队列(参数:timeout和block),), ***生产消费者模型 一丶互斥锁 含义: 每个对象都对应于一个可称为" 互斥锁&qu ...
- 《python开发技术详解》|百度网盘免费下载|Python开发入门篇
<python开发技术详解>|百度网盘免费下载|Python开发入门篇 提取码:2sby 内容简介 Python是目前最流行的动态脚本语言之一.本书共27章,由浅入深.全面系统地介绍了利 ...
- 【Python】使用Supervisor来管理Python的进程
来源 : http://blog.csdn.net/xiaoguaihai/article/details/44750073 1.问题描述 需要一个python的服务程序在后台一直运行,不能让 ...
随机推荐
- 2017西安网络赛 F
f(cos(x))=cos(n∗x) holds for all xx. Given two integers nn and mm, you need to calculate the coeffic ...
- POJ_2769同余问题
Reduced ID Numbers Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9310 Accepted: 374 ...
- Convex(扫描线降维)
Convex Time Limit: 10000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- SPI、I2C、UART(转)
UART与USART(转) UART需要固定的波特率,就是说两位数据的间隔要相等. UART总线是异步串口,一般由波特率产生器(产生的波特率等于传输波特率的16倍).UART接收器.UART发送器组成 ...
- c语言中标识符的作用域
1.代码块作用域(block scope) 位于一对花括号之间的所有语句称为一个代码块,在代码块的开始位置声明的标识符具有代码块作用域,表示它们可以被这个代码中的所有语句访问.函数定义的形式参数在函数 ...
- chorme浏览器的Access-Control-Allow-Origin拦截限制
今天在公司调试一个项目,这个项目的前后端是分离开的,也就是说前后端是在两个站点上的.我负责的前端页面在请求后端数据的时候数据可以拿到,但是chrome安全级别高,自动拦截跨域和站点的数据请求及交互,出 ...
- UEP-按钮控制及时间
按钮的判断 var record = ajaxgrid.getAllRecords(); if(record.length>0){ var isPack=record[0].get(" ...
- 自定义alert弹框
/**************** UIAlertControllerStyleAlert *************************/ /*创建一个 可以自定义文字颜色和字体大小的IAler ...
- Spark算子--mapPartitions和mapPartitionsWithIndex
mapPartitions--Transformation类算子 代码示例 result mapPartitionsWithIndex--Transformation类算子 代码示例 result ...
- TP5.0 excel 导入导出
引第三方的phpexcel类库放到 ThinkPHP\Library\Vendor\demo下,自己建的文件夹demo 再将Excel.class放到ThinkPHP\Library\Org\clas ...