0
点赞
收藏
分享

微信扫一扫

Python-多进程


当程序运行前是静态的,程序运行时在电脑中会创建程序的进程,比如我们打开一个QQ,此时为QQ创建了一个进程,当我们再打开一个QQ的时候,系统会再为QQ创建一个进程

这就是进程,在Windows操作系统中可以在任务管理器中查看所有程序的进程。Linux通过ps -le 查看计算机中所有的进程

Python-多进程_数据

一,多进程的实现

多进程和多线程差不多,方法类似,只是调用的类不同

p1 = multiprocessing.Process(target=test)
p1.start()
p2 = multiprocessing.Process(target=test1)
p2.start()

Python-多进程_进程池_02

但是进程占用的资源比较大,子进程在运行过程中,会将主进程的代码复制一份,即代码是共享的,数据不共享

二,进程和线程的区别

进程,能够完成多任务,比如一台电脑上多个qq
线程,能够完成多任务,比如一个qq中的多个聊天窗口
一个进程里面至少有一个主线程

三,进程间的通讯

在线程中,数据可以进行通讯,但是在进程中,数据是不共享的,可是怎么实现进程间的数据通sc讯呢

  • 1,通过socket完成进程间的通讯
  • 2,通过文件实现进程间的通讯
  • 3,通过队列实现进程间的通讯

通过队列实现
线程是在内存中开辟的,而队列也是存在内存中的,所以我们可以通过队列进行进程间的通讯
这里模拟一个进程下载文件,一个进程下载文件的过程:
1,实例化队列对象

q = multiprocessing.Queue() #创建队列

将队列的对象作为参数传入进程中:

p1 = multiprocessing.Process(target=download,args=(q,)) #传入队列的引用
p2 = multiprocessing.Process(target=analyse,args = (q,))

之后就能在队列中进行数据的读取操作
通过q.empty()判断队列是否为空
通过q.put() 将数据放入队列中
通过q.get()将队列头元素出队
案例演示:

import multiprocessing

def download(q):
#模拟数据下载
data = [11,22,33,44]
for t in data:
q.put(t) #向队列添加数据
print("数据一下载完成并写入队列")
def analyse(q):
#模拟数据处理
waiting_data = list() #创建空的列表
while True:
data = q.get() #获取队列的第一个元素
waiting_data.append(data)
if q.empty():
break
print ("下载到的数据为:")
for i in waiting_data:
print(i)


def main():
q = multiprocessing.Queue() #创建队列
p1 = multiprocessing.Process(target=download,args=(q,)) #传入队列的引用
p2 = multiprocessing.Process(target=analyse,args = (q,))
p1.start()
p2.start()
if __name__ == "__main__":
main()

Python-多进程_数据_03

四,进程池

当进程较少时,可以通过,multiprocessing的Process方法进行创建,当涉及的进程较多时,可以通过Pool方法创建进程池,创建多个进程,重复利用已用的进程
进程池的创建
通过​​​Pool()​​​来创建
通过 ​​​apply_async()​​​来进行添加
通过​​​close()方法关闭进程池 通过​​​join()方法堵塞程序,等待进程池内的所有程序执行完
前面的进程中学到了,主进程会在子进程都执行完后再结束,但是进程池不会等子进程

所以需要利用​​join​​方法

po = multiprocessing.Pool(3)  # 定义容量为3的进程池
#向进程池添加10个数据但是此时进程此=池的容量只有3 所以进程池会先执行前3>个任务,当前三个任务执行完成后再继续向下执行下面的7个任务
for i in range(0,10):
po.apply_async(worker,(i,)) # 向进程池添加数据 第一代表要执行的
进程的函数 第二个代表要传递的参数元祖
print("%d加入进程池------------"%(i))
po.close() # 关闭进程池 此时进程池不会接收新的请求
po.join() # 该方法会堵塞,等待所有的子进程执行完后执行下面的代码
print("--------end-----------")

案例演示:

import multiprocessing
import os,time
def worker(msg):
time_start = time.time()
print("开始执行,进程号为:%d"%(os.getpid()))
time.sleep(random.random()*2)
time_end = time.time()
print("执行完毕,经历时间为:%0.2f"%(time_end-time_start))
def main():
print("--------start----------")
po = multiprocessing.Pool(3) # 定义容量为3的进程池
#向进程池添加10个数据但是此时进程此=池的容量只有3 所以进程池会先执行前3>个任务,当前三个任务执行完成后再继续向下执行下面的7个任务
for i in range(0,10):
po.apply_async(worker,(i,)) # 向进程池添加数据 第一代表要执行的
进程的函数 第二个代表要传递的参数元祖
print("%d加入进程池------------"%(i))
po.close() # 关闭进程池 此时进程池不会接收新的请求
po.join() # 该方法会堵塞,等待所有的子进程执行完后执行下面的代码
print("--------end-----------")
if __name__ == "__main__":
main()


举报

相关推荐

0 条评论