Python_多进程,,Python 多进程


Python 多进程库 multiprocessing ,支持子进程、通信、数据共享、执行不同形式的同步

多进程,绕过gil ,实现多核的利用,多进程也是原生进程,由操作系统维护

在pycharm中,可能没有办法正常使用multiprocessing.Process,最好是在Linux中运行

Process用于创建进程模块
Pool用于创建管理进程池
Queue用于进程通信,资源共享
Pipe用于管道通信
Manager用于资源共享,同步进程

1.Process类


Process(group = None,target =None,name=None, args=[ ], kwargs={ })

group线程组
target要执行的方法
name进程名
args/kwargs要传入方法的参数

process属性&方法:

authkey进程的身份验证密钥
daemon同thread的setDaemon,守护进程
exitcode进程运行时为None,若为—N,则表示被信号N结束
pid进程号
name进程名
is_alive()返回进程是否正在运行
join([timeout])阻塞到线程结束或到timeout值
start()进程准备就绪,等待CPU调度
run()start()调用run方法,如果实例进程时未制定传入target,start执行默认run()方法。
terminate()不管任务是否完成,立即停止工作进程

多进程的创建:

技术分享图片
#!/usr/bin/python# -*- coding:utf-8 -*-‘‘‘多进程的创建‘‘‘from multiprocessing import Processimport timedef fun(name):    time.sleep(1)    print(‘hello,%s‘ % name)    print(‘----‘)if __name__ ==‘__main__‘:    for i in range(5):                # 进程同步        p = Process(target=fun, args=(‘Presley‘,))        p.start()    p.join()    print(‘结束。‘)
多进程

进程id :

技术分享图片
#!/usr/bin/python3# -*- coding:utf-8 -*-from multiprocessing import Processimport osdef info(title):    print(title)    print(‘moudle name :‘,__name__)    print(‘parent process id ‘, os.getppid())             print(‘process id ‘, os.getpid())                  if __name__ ==‘__main__‘:    info(‘hei. ‘)          # pycharm id和 主进程id                 for i in range(3):        p = Process(target=info, args=(‘Presley‘,))     # 主进程id   和 info 子进程id        p.start()    p.join()
多进程id技术分享图片
hei. moudle name : __main__parent process id  1610process id  1826Presleymoudle name : __main__parent process id  1826process id  1827Presleymoudle name : __main__parent process id  1826process id  1828Presleymoudle name : __main__parent process id  1826process id  1829
result

2.Queue类


不同进程间内存是不共享的,想要实现两个进程间的数据交换,可以用Queue进行进程间通讯

queue是在多进程中做了一层封装的队列,以保证在当前进程里进程安全

方法:queue

进程中的队,以保证进程安全

技术分享图片
from multiprocessing import Process,Queuedef info(q):    #  global q       # 错误,queue中 ,global 不行,因为子进程无法访问父进程的内存数据    q.put([34, None, ‘yes‘])if __name__ ==‘__main__‘:    q = Queue()    for i in range(3):        p = Process(target=info, args=[q,])      # 多个子进程的数据可以都可以放父进程数据        p.start()        print(‘来自父进程%s:%s‘%(i, q.get()))    p.join()
多进程_queue技术分享图片
来自父进程0:[34, None, ‘yes‘]来自父进程1:[34, None, ‘yes‘]来自父进程2:[34, None, ‘yes‘]
result

3.Pipe类


管道操作(双向队列):会返回一对对象,管道的两端分别赋给子进程和父进程

和队列操作差不多,所以一般运用队列较多

方法:

send()发送序列
recv()接收序列
fileno()返回一个整型的文件描述符
close()退出
poll()判断子进程是否结束
send_bytes()以bytes格式发送序列
recv_bytes()以bytes格式接收序列
技术分享图片
from multiprocessing import Process,Pipeimport timedef info(conn):    time.sleep(0.5)    conn.send([32,None,‘ni hao wa‘])    conn.close()if __name__==‘__main__‘:    conn_parent ,conn_child = Pipe()    print(conn_parent.fileno())           for i in range(3):        p = Process(target=info,args=(conn_child,))        print(bool(conn_child.poll))        # 进程是否结束        p.start()        # 如果没有消息可接收,recv方法会一直阻塞。如果管道已经被关闭,那么recv方法会抛出EOFError。        print(‘父端接收%s:%s‘% (i,conn_parent.recv()))    p.join()
多进程_Pipe技术分享图片
200True父端接收0:[32, None, ‘ni hao wa‘]True父端接收1:[32, None, ‘ni hao wa‘]True父端接收2:[32, None, ‘ni hao wa‘]
result

4.Manager


通过Manager可以简单的使用list,dict,Namespace,Lock,RLock,Semaphore,BoundedSemaphore,Condition,Event,Barries,Value+Arrary等类型的高级接口

Manager()返回的manager对象控制了一个server进程,此进程包含的python对象可以被其他的进程通过proxies来访问。从而达到多进程间数据通信且安全

例:对list,dict的应用例子:

技术分享图片
#!/usr/bin/python3# -*- coding:utf-8 -*-from multiprocessing import Process,Managerdef fun(d,l,n):    d[2] = ‘3‘    d[‘e‘] = ‘e‘    d[34] = None    l.append(n)    print(l)if __name__ == ‘__main__‘:    with Manager() as manager:        d = manager.dict()        l = manager.list()        join_list = []        for i in range(6):            p = Process(target=fun, args=(d,l,i))            p.start()            join_list.append(p)        for res in join_list:            res.join()            print(l)        print(d)
example技术分享图片
[5][5, 2][5, 2, 3][5, 2, 3, 0][5, 2, 3, 0, 4][5, 2, 3, 0, 4, 1][5, 2, 3, 0, 4, 1][5, 2, 3, 0, 4, 1][5, 2, 3, 0, 4, 1][5, 2, 3, 0, 4, 1][5, 2, 3, 0, 4, 1][5, 2, 3, 0, 4, 1]{2: ‘3‘, ‘e‘: ‘e‘, 34: None}
result

Manager的详细参考:https://www.aliyun.com/jiaocheng/490316.html

5.Pool 类(进程池)


当进程数过多时,用于限制进程数

异步:进程并行

同步:进程串行

方法:

apply_async(func,args,kwds,callback)

进程异步,并行(func:执行一个函数,args/ dwds:进程参数,callback:Foo执行结果返回到callback执行的函数中)

apply(func,args,kwds)进程同步,串行
close()关闭进程池
terminate()结束工作进程,不在处理未完成的任务
join()主进程阻塞,等待子进程执行完毕
技术分享图片
from multiprocessing import Pool,freeze_supportimport timedef Foo(i):    time.sleep(1)    print(‘exec..‘)    return i+100     # 返回到Bar中def Bar(arg):    print(‘来自Foo 的i :‘,arg)   # 接收 Foo中 的返回值if __name__ == ‘__main__‘:    freeze_support()       # 仅在Windows上才导入此模块进程程序才不会出错,Linux上不用    pool = Pool(5)     # 限制每次进行的进程数为 5    for i in range(10):        pool.apply_async(func=Foo, args=(i,),callback=Bar)  # 进程异步    # callback 把前面func的放在Bar中打印        # pool.apply(func=Foo, args=(i,))         # 同步,串行   # 没有callback属性    print(‘结束。。‘)    pool.close()           # 注意:join必须放在close()后面,否则将不会等待子进程打印结束,而直接结束    pool.join()
进程池技术分享图片
结束。。exec..exec..exec..exec..exec..来自Foo 的i : 104来自Foo 的i : 102来自Foo 的i : 103来自Foo 的i : 100来自Foo 的i : 101exec..exec..exec..exec..exec..来自Foo 的i : 105来自Foo 的i : 106来自Foo 的i : 107来自Foo 的i : 108来自Foo 的i : 109
异步结果技术分享图片
exec..exec..exec..exec..exec..exec..exec..exec..exec..exec..结束。。
同步结果

Python_多进程

评论关闭