Python:进程池,同步和异步,进程池通信示例

进程池:
主要方法:

p.apply_async(func(函数名)[,args(传递给func的参数列表--元组形式)[,kwds(传递给func的关键字参数列表)]])        非阻塞方式调用func

p.close()  关闭进程池,防止进一步操作(进程池不接受新的任务)

p.join() 阻塞进程

enumerate() 不管任务是否完成,立即终止,如果使用异步提交任务,等进程池内任务都处理完,需要用get()来收集结果

使用场景:利用Python进行系统管理的时候,同时操作多个文件目录,或者远程控制多台主机,并行操作可以节约大量时间

阻塞:遇到I/O就发生阻塞,程序一旦阻塞操作就停在原地,并且立刻释放CPU资源

非阻塞:没有遇到I/O操作或者通过某种手段让程序即使遇到IO操作也不会停在原地而去执行其他操作,力求尽可能多的占有CPU资源

同步与异步:提交任务的两种方式:
同步调用:提交完任务后就在原地等待,直到任务运行完毕后,拿到任务的返回值,才能继续执行下一行的代码

异步调用:提交完任务后,不在原地等待,直接执行下一行代码

进程池同步和异步操作:

#异步:不用等待当前进程执行完毕,随时根据系统调度来进行进程切换
import os
import time
from multiprocessing import Pool

def learn(n):
    print('study')
    time.sleep(2)
    return n**2

if __name__=='__main__':
    #创建进程池,最大进程数为3
    p=Pool(3)
    list=[]
    for i in range(6):
        result=p.apply_async(learn,args=(i,))#learn函数名,i为函数learn的参数
        list.append(result)#把结果添加到list列表里

    p.close()#关闭进程池,关闭后p不再接受新的请求
    p.join()#等待p中所有的子程序执行完成,必须放在close语句之后
    for j in list:
        print(j.get())#使用get获取apply_async
#同步:apply(同步阻塞)需要等待当前子进程执行完毕后,在执行下一个进程(按顺序执行)
import os
import time
from multiprocessing import Pool

def learn(n):
    print('study')
    time.sleep(2)
    return n**2

if __name__=='__main__':
    #创建进程池,最大进程数为3
    p=Pool(3)
    list=[]
    for i in range(6):
        result=p.apply(learn,args=(i,))#learn函数名,i为函数learn的参数
        list.append(result)#把结果添加到list列表里
    print(list)

进程池的通信:

Pool创建进程池,需要使用multiprocessing.Manager()中Queue()

if multiprocessing.Queue()

Manager()模块专门用来做数据共享,支持很多类型,如value,array,list,dict,Queue,Lock等

multiprocessing模块下的Queue为进程提供服务;

queue模块下的Queue为线程提供服务;

队列实例化 q=Manager(),Queue()

import os
from multiprocessing import Pool,Manager

def rd(q):
    print(f'rd启动{os.getpid()},父进程{os.getppid()}')
    for i in range(q.qsize()):#q.qsize()返回队列中数据的数量
        print('取出数据:',q.get())

def wd(q):
    print(f'wd启动{os.getpid()},父进程{os.getppid()}')
    for i in '123':
        print('wd中的:',i)
        q.put(i)#把字符串123中的某个数据放到队列中

if __name__=='__main__':
    print('begin,',os.getpid())
    q=Manager().Queue()
    #创建进程池
    p=Pool()
    #使用异步操作
    p.apply_async(wd,args=(q,))
    p.apply_async(rd,args=(q,))
    p.close()#关闭进程池
    p.join()#阻塞主进程
    print('end',os.getpid())

输出结果为:
begin, 524
wd启动7628,父进程524
wd中的: 1
wd中的: 2
wd中的: 3
rd启动10488,父进程524
取出数据: 1
取出数据: 2
取出数据: 3
end 524

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值