python --- mulitprocessing(多进程)模块使用
1. 什么是进程?
进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。
一个进程至少包含一个线程。
2. 在python中有了多线程编程为何还需要多进程编程?
在python中由于有GIL(全局解释器锁)的存在,在任一时刻只有一个线程在运行(无论你的CPU是多少核),无法实现真正的多线程。那么该如何让python程序真正的并行运行呢?答案就是不要使用多线程,使用多进程。python标准库提供了multiprocessing模块(multiprocessing
是一个和threading
模块类似,提供API,生成进程的模块。multiprocessing
包提供本地和远程并发,通过使用子进程而不是线程有效地转移全局解释器锁。),它的API几乎复制了threading模块的API,当然它还有一行threading模块没有的API。
例一(multiprocessing模块的简单使用):
import multiprocessing,time class Task(multiprocessing.Process):
def __init__(self):
super(Task, self).__init__() def run(self):
print("Process---%s" % self.name)
time.sleep(2) if __name__ == "__main__":
for i in range(1, 8+1):
t = Task()
t.start()
注:由于multiprocessing模块基本的API同threading模块,就不挨个演示了,本文主要讲解multiprocessing模块不同于threading模块的API的使用。要了解其他同threading模块相同的API的使用,可参见:http://www.cnblogs.com/God-Li/p/7732407.html
multiprocessing.Process源码:
class Process(object):
def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):
self.name = ''
self.daemon = False #守护进程标志,必须在start()之前设置
self.authkey = None #The process’s authentication key (a byte string).
self.exitcode = None #The child’s exit code. This will be None if the process has not yet terminated. A negative value -N indicates that the child was terminated by signal N.
self.ident = 0
self.pid = 0 #进程ID。在生成进程之前,这将是Non。
self.sentinel = None #A numeric handle of a system object which will become “ready” when the process ends. def run(self):
pass def start(self):
pass def terminate(self):
"""
Terminate the process. On Unix this is done using the SIGTERM signal; on Windows TerminateProcess() is used.
Note that exit handlers and finally clauses, etc., will not be executed.
Note that descendant processes of the process will not be terminated – they will simply become orphaned.
:return:
"""
pass def join(self, timeout=None):
pass def is_alive(self):
return False
multiprocessing模块中的队列:
class multiprocessing.
Queue
([maxsize])实现除task_done()
和join()
之外的queue.Queue
的所有方法,下面列出queue.Queue中没有的方法:
class multiprocessing.Queue([maxsize])
close()
"""
指示当前进程不会在此队列上放置更多数据。
The background thread will quit once it has flushed all buffered data to the pipe.
当队列被垃圾回收时,这被自动调用。
""" join_thread()
"""
加入后台线程。这只能在调用close()之后使用。它阻塞直到后台线程退出,确保缓冲区中的所有数据都已刷新到pipe。
默认情况下,如果进程不是队列的创建者,那么在退出时它将尝试加入队列的后台线程。
该进程可以调用cancel_join_thread()使join_thread()不执行任何操作
""" cancel_join_thread()
"""
使join_thread()不执行任何操作
"""
class multiprocessing.
SimpleQueue是class
multiprocessing.
Queue
([maxsize])的简化,只有三个方法------empty(), get(), put()
class multiprocessing.
JoinableQueue
([maxsize])是class multiprocessing.
Queue
([maxsize])的子类,增加了take_done()和join()方法
注:由于进程之间内存空间不共享,所以必须将实例化后的queue对象当作参数传入其他进程,其他进程才能使用。而且,每传入一次相当于克隆一份,与原来的queue独立,只是python会同步queue中的数据,而不是像在多线程的queue数据只有一份。
进程之间的通信:
multiprocessing.
Pipe
([duplex]) --------------- 返回表示管道末端的Connection
对象(类似与socket中的连接可用于发送和接收数据)的(conn1, conn2)。
如果duplex是True
(默认值),则管道是双向的。如果duplex是False
,则管道是单向的:conn1
只能用于接收消息,conn2
用于发送消息。
例二(multiprocessing.Pipe使用演示):
import multiprocessing,time class Processing_1(multiprocessing.Process):
def __init__(self, conn):
super(Processing_1, self).__init__()
self.conn = conn
def run(self):
send_data = "this message is from p1"
self.conn.send(send_data) #使用conn发送数据
time.sleep(0.8)
recv_data = self.conn.recv() #使用conn接收数据
print("p1 recv: " + recv_data)
self.conn.close() class Processing_2(multiprocessing.Process):
def __init__(self, conn):
super(Processing_2, self).__init__()
self.conn = conn def run(self):
send_data = "this message is from p2"
self.conn.send(send_data)
time.sleep(0.8)
recv_data = self.conn.recv()
print("p2 recv: " + recv_data)
self.conn.close() if __name__ == "__main__":
conn1, conn2 = multiprocessing.Pipe() #实例化Pipe对象,conn1, conn2分别代表连接两端 p1 = Processing_1(conn1) #将连接对象当作参数传递给子进程
p2 = Processing_2(conn2) p1.start()
p2.start() p1.join()
p2.join()
multiprocessing.Pipe使用演示
进程之间的数据共享:
multiprocessing.
Manager
() ----------- 返回开始的SyncManager
对象,可用于在进程之间共享对象。返回的管理器对象对应于生成的子进程,并且具有将创建共享对象并返回相应代理的方法。管理器进程将在垃圾收集或其父进程退出时立即关闭。
例三(Manager的简单使用):
import multiprocessing,time
import os class Processing(multiprocessing.Process):
def __init__(self, d, l):
super(Processing, self).__init__()
self.d = d
self.l = l def run(self):
self.d[os.getpid()] = os.getpid() #当作正常dict使用即可
self.l.append(1)
print(self.l) if __name__ == "__main__": manager = multiprocessing.Manager() #生成Manager 对象
d = manager.dict() #生成共享dict
l = manager.list() #生成共享list p_s = []
for i in range(10):
p = Processing(d, l)
p.start()
p_s.append(p) for p in p_s:
p.join() print(d)
print(l)
Manager简单使用
manager可以生成以下共享数据对象(常用):
Event
()-
Create a shared
threading.Event
object and return a proxy for it.
Lock
()-
Create a shared
threading.Lock
object and return a proxy for it.
Namespace
()-
Create a shared
Namespace
object and return a proxy for it.
Queue
([maxsize])-
Create a shared
queue.Queue
object and return a proxy for it.
RLock
()-
Create a shared
threading.RLock
object and return a proxy for it.
Semaphore
([value])-
Create a shared
threading.Semaphore
object and return a proxy for it.
Array
(typecode, sequence)-
Create an array and return a proxy for it.
Value
(typecode, value)¶-
Create an object with a writable
value
attribute and return a proxy for it.
dict
()dict
(mapping)dict
(sequence)-
Create a shared
dict
object and return a proxy for it.
list
()list
(sequence)-
Create a shared
list
object and return a proxy for it.
进程锁:
进程锁有两种multiprocessing.
Lock(非递归锁)和
multiprocessing.
RLock(递归锁)。
multiprocessing.
Lock(非递归锁):一旦进程或线程获得了锁,随后从任何进程或线程获取它的尝试将阻塞,直到它被释放;任何进程或线程都可以释放它。
multiprocessing.
RLock(递归锁): A recursive lock must be released by the process or thread that acquired it. Once a process or thread has acquired a recursive lock, the same process or thread may acquire it again without blocking; that process or thread must release it once for each time it has been acquired.
这两种锁都只用两种方法:acquire
(block=True, timeout=None)和release
(),它们的使用基本和线程锁类似(只不是要把锁的示例对象当作参数传入其他的进程):http://www.cnblogs.com/God-Li/p/7732407.html
进程池:
为了便于对多进程的管理,通常使用进程池来进行多进程编程(而不是使用multiprocessing.Process)。
例:
import multiprocessing,os
import time def run():
print(str(os.getpid()) + "-----running")
time.sleep(2)
print(str(os.getpid()) + "-----done") def done():
print("done") def error():
print("error") if __name__ == "__main__":
pool = multiprocessing.Pool(processes=4) #实力化进程池对象 for i in range(8):
# pool.apply(func=run) #进程池中的进程串行运行
pool.apply_async(func=run) pool.close()
pool.join()
print("finish....")
Pool对象常用方法:
apply
(func[, args[, kwds]])-
Call func with arguments args and keyword arguments kwds. It blocks until the result is ready. Given this blocks,
apply_async()
is better suited for performing work in parallel. Additionally, func is only executed in one of the workers of the pool.将任务提交到进程池,只有一个进程在工作,其他进程处于阻塞状态(相当于串行运行)。
apply_async
(func[, args[, kwds[, callback[, error_callback]]]])-
A variant of the
apply()
method which returns a result object.If callback is specified then it should be a callable which accepts a single argument. When the result becomes ready callback is applied to it, that is unless the call failed, in which case the error_callback is applied instead.
If error_callback is specified then it should be a callable which accepts a single argument. If the target function fails, then the error_callback is called with the exception instance.
Callbacks should complete immediately since otherwise the thread which handles the results will get blocked.
将任务提交到进程池,多个进程(进程数量由之前实例化时的processes参数设置)同时运行,callback工作进程完成时(由当前进程的父进程)调用由此传入的任务,error_callback工作进程出错时(由当前进程的父进程)调用由此传入的任务。
close
()-
Prevents any more tasks from being submitted to the pool. Once all the tasks have been completed the worker processes will exit.
调用此方法后进程池不能在提交新的任务
terminate
()-
Stops the worker processes immediately without completing outstanding work. When the pool object is garbage collected
terminate()
will be called immediately.立即停止工作进程,而不需要等待未完成的工作进程。
join
()-
Wait for the worker processes to exit. One must call
close()
orterminate()
before usingjoin()
.等待进程池中的工作进程结束(在此之前必须调用close()或者terminate())。
注:Pool对象在生成时进程内的进程(阻塞)就已经启动,使用apply(或者apply_async)方法只是将任务提交给线程池,不会再建立新进程。
python --- mulitprocessing(多进程)模块使用的更多相关文章
- python multiprocessing多进程模块
原文:https://blog.csdn.net/CityzenOldwang/article/details/78584175 多进程 Multiprocessing 模块 multiprocess ...
- python学习笔记——multiprocessing 多进程模块Process
系统自带的fork模块创建的多进程是基于Linux或Unix平台的,而window平台并不支持: python中的multiprocess为跨平台版本的多进程模块,支持子进程.通信和共享数据.执行不同 ...
- python笔记9 线程进程 threading多线程模块 GIL锁 multiprocessing多进程模块 同步锁Lock 队列queue IO模型
线程与进程 进程 进程就是一个程序在一个数据集上的一次动态执行过程.进程一般由程序.数据集.进程控制块三部分组成.我们编写的程序用来描述进程要完成哪些功能以及如何完成:数据集则是程序在执行过程中所需要 ...
- Python学习之模块进程函数详解
今天在看<Beginning Linux Programming>中的进程相关部分,讲到Linux几个进程相关的系统函数: system , exec , fork ,wait . Pyt ...
- python网络-多进程(21)
一.什么是进程 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实 ...
- python 使用多进程实现并发编程/使用queue进行进程间数据交换
import time import os import multiprocessing from multiprocessing import Queue, pool ""&qu ...
- Python多线程多进程
一.线程&进程 对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程, ...
- Python开发【模块】:logging日志
logging模块 很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误.警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式 ...
- 进程,线程,以及Python的多进程实例
什么是进程,什么是线程? 进程与线程是包含关系,进程包含了线程. 进程是系统资源分配的最小单元,线程是系统任务执行的最小单元. 打个比方,打开word,word这个程序是一个进程,里面的拼写检查,字数 ...
随机推荐
- python函数定义
刚学用Python的时候,特别是看一些库的源码时,经常会看到func(*args, **kwargs)这样的函数定义,这个*和**让人有点费解.其实只要把函数参数定义搞清楚了,就不难理解了. 先说说函 ...
- CVE-2017-8464复现 (远程快捷方式漏洞)
我们的攻击机IP是192.168.222.133 目标机IP是192.168.222.132 我们首先生成一个powershell msfvenom -p windows/x64/meterprete ...
- HDU 2504 又见GCD(最大公约数与最小公倍数变形题)
又见GCD Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Subm ...
- Educational Codeforces Round 21 D.Array Division(二分)
D. Array Division time limit per test:2 seconds memory limit per test:256 megabytes input:standard i ...
- C#的LINQ
在过去如果我们如果需要去查询某些集合或者数组里面的某些元素,我们需要写出大量的带有筛选的遍历集合的代码,但是有了Linq之后,我们就不用写出那些冗余麻烦的遍历代码,只需要关注其中的筛选,排列的函数就可 ...
- 番外篇--Moddule Zero启动模板
1.3 ABPZero - 启动模板 1.3.1 简介 使用ABP和moudle-zero开始一个新项目的最简单的方式是在模板页创建模板.记住要勾选 Include module zero. 在创建并 ...
- 【干货】平安打卡神器E行销刷脸考勤破解,是怎么做到的?
很多人好奇平安E行销打卡到底是怎么破解的,为什么明明需要连接公司职场WiFi才可以参会,才可以刷脸打卡.为什么不用去公司,在家里,或者外面只要有4G或WiFi的地方都可以.今天我就来给大家解密.把原理 ...
- tp系统常量定义
(2013-03-06 14:16:31) 转载▼ 标签: it 是已经封装好的系统常量 主要是用在控制器下面的动作当中 这样能很大的提高我们的开发效率 主要有下面的一些 手册上面都有的 ...
- thinkPHP内置字符串截取msubstr函数用法详解
作者:陈达辉 字体:[增加 减小] 类型:转载 时间:2016-11-15 我要评论 这篇文章主要介绍了thinkPHP内置字符串截取函数用法,结合实例形式分析了thinkPHP内置的字符串截取函数功 ...
- ProtoBuf 与 gRPC
用 Protobuf 很久了,但是一直觉得很简单,所以就没有做一个总结,今天想尝试一下 gRPC,顺带就一起总结一下.ProtoBuf 是个老同志了,应该是 2010 的时候发布的,然后被广泛使用,目 ...