攻克python3-进程
进程
进程是程序的一段执行过程,是个动态概念,是操作系统调度的最小单位。
multiprocessing模块
Process 类用来描述一个进程对象。创建子进程的时候,只需要传入一个执行函数和函数的参数即可完成 Process 示例的创建。
star() 方法启动进程
j
oin() 方法实现进程间的同步,
等待所有进程退出。
close() 用来阻止多余的进程涌入进程池 Pool 造成进程阻塞。
multiprocessing.Process(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)
target 是函数名字,需要调用的函数
args 函数需要的参数,以 tuple 的形式传入
创建子进程
直接调用
from multiprocessing import Process import time def f(name): time.sleep(2) print('hello', name) if __name__ == '__main__': p = Process(target=f, args=('bob',)) p.start() p.join()
继承式调用
from multiprocessing import Process import time class MyProcess(Process): def __init__(self,name): super().__init__() self.name=name def run(self): print('task <%s> is runing' % self.name) time.sleep(2) print('task <%s> is done' % self.name) if __name__ == '__main__': p=MyProcess('egon') p.start() print('主')
与线程一样run方法必须重写
进程间通信
这里介绍只有具有亲缘关系的进程才能进行通信。
进程queue
线程queue共用内存空间
进程queue不共用内存空间,只是通过传递数据来达到进程间通信的目的
from multiprocessing import Process,Queue import threading,queue def fun(qq): qq.put("wurui") if __name__ == '__main__': q=Queue() # q=queue.Queue() p=Process(target=fun , args=(q,)) p.start() print(q.get()) p.join()
管道通信pipe
from multiprocessing import Process,Pipe def f(conn): conn.send("hello!") if __name__ == '__main__': p_conn,c_conn=Pipe() p=Process(target=f,args=c_conn) p.start() print(p_conn.recv()) p.join()
manager
A manager object returned by Manager()
controls a server process which holds Python objects and allows other processes to manipulate them using proxies.
A manager returned by Manager()
will support types list
, dict
, Namespace
, Lock
, RLock
, Semaphore
, BoundedSemaphore
, Condition
, Event
, Barrier
, Queue
, Value
and Array
. For example:
from multiprocessing import Process,Manager import os def f(d,l): d[os.getpid()]=os.getpid() l.append(os.getpid()) print(l) if __name__ == '__main__': with Manager() as m: d=m.dict() l=m.list(range(5)) p_list=[] for i in range(10): p=Process(target=f,args=(d,l)) p.start() p_list.append(p) for j in p_list: j.join() print(d) print(l)
lock(屏幕锁:防止一个进程未打印完成,另一个进程插入)
def f(l,i): l.acquire() print("hello",i) l.release() if __name__ == '__main__': l=Lock() for i in range(10): Process(target=f,args=(l,i)).start()
进程池
在利用Python进行系统管理的时候,特别是同时操作多个文件目录,或者远程控制多台主机,并行操作可以节约大量的时间。当被操作对象数目不大时,可以直接利用multiprocessing中的Process动态成生多个进程,10几个还好,但如果是上百个,上千个目标,手动的去限制进程数量却又太过繁琐,这时候进程池Pool发挥作用的时候就到了。
Pool可以提供指定数量的进程,供用户调用,当有新的请求提交到pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到规定最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来它。
from multiprocessing import Process, Pool,Lock import time import os ''' 如何在进程池中使用进程锁 ''' def Foo(i): # l.acquire() time.sleep(2) print("in process",os.getpid()) # l.release() return i + 100 #返回值由回调函数接收 def Bar(arg): print('-->exec done:', arg,os.getpid()) if __name__ == '__main__': pool = Pool(processes=3) #允许进程池同时放3入个进程 # l = Lock() print("主进程",os.getpid()) for i in range(10): pool.apply_async(func=Foo, args=(i,), callback=Bar) #callback=回调 #pool.apply(func=Foo, args=(i,)) #串行 #pool.apply_async(func=Foo, args=(i,)) #并行 # print('end') pool.close() #先close在join pool.join() #进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。.join()
- pool.apply_async()用来向进程池提交目标请求。
- pool.join()是用来等待进程池中的worker进程执行完毕,防止主进程在worker进程结束前结束。但pool.join()必须使用在pool.close()或者pool.terminate()之后。
- close()跟terminate()的区别在于close()会等待池中的worker进程执行结束再关闭pool,而terminate()则是直接关闭。
- result.successful()表示整个调用执行的状态,如果还有worker没有执行完,则会抛出AssertionError异常。
- 利用multiprocessing下的Pool可以很方便的同时自动处理几百或者上千个并行操作,脚本的复杂性也大大降低.