Day06 Python 中的进程(创建进程、队列、进程池)

Day06 Python 中的进程(创建进程、队列、进程池),第1张

一、进程是什么? 1、定义

一个程序运行起来后,代码+用到的资源 称之为进程,它是 *** 作系统分配资源的基本单元。

Pass:进程是资源分配的最小单位,线程是cpu调度的最小单位

2、进程中的状态

工作中,任务数往往大于CPU核数,也就是说有部分任务正在执行,也有另一部分任务正在等待CPU进行执行,也就出现了不同的状态。
五种进程状态:新建、就绪、堵塞、运行、死亡

  • 就绪态:运行的条件都已经满足,等待CPU执行
  • 执行态:正在执行的进程
  • 等待态:满足运行条件之后,等待CPU执行
二、创建进程 1、常用的属性 name pid
import os  # 多种 *** 作系统接口模块
from multiprocessing import Process   #在multiprocessing模块中导入process类
def f1():
    print(f'f1子进程的id是{os.getpid()},父进程id为{os.getppid()}')
def f2():
    print(f'f2子进程的id是{os.getpid()},父进程id为{os.getppid()}')
if __name__ == '__main__':
    # 创建子进程
    p1 = Process(target=f1)
    p2 = Process(target=f2)
    # 启动进程
    p1.start()
    p2.start()
    # 修改进程名
    p1.name = 'our'
    print('p1的子进程名是',p1.name)
    print(f'主进程的id是{os.getpid()},父进程id为{os.getppid()}')
    
# 结果:
# p1的子进程名是 our
# 主进程的id是18532,父进程id为7904
# f1子进程的id是1632,父进程id为18532
# f2子进程的id是26292,父进程id为18532
2、常用的方法 is_alive()和join()

start()启动
is_alive()判断进程子进程是否还活着,如果存活则返回True,否则为False;
join() 阻塞
terminate()不管任务是否完成,立即终止进程
例子1:

from multiprocessing import Process
def study(name):
    print(f'{name}学习很认真')
def smile(name):
    print(f'{name}能笑到最后呢')
if __name__ =='__main__':
    p1 = Process(target=study,args=('任嘉伦',))
    p2 = Process(target=smile,args=('任国超',))
    p1.start()
    p2.start()
    print('p1的状态是',p1.is_alive())
    print('p2的状态是',p2.is_alive())
# 结果:
# p1的状态是 True
# p2的状态是 True
# 任嘉伦学习很认真
# 任国超能笑到最后呢

例子2:

# 创建的进程带参数
from multiprocessing import Process
def study(name):
    print(f'{name}学习很认真')
def smile(name):
    print(f'{name}能笑到最后呢')
if __name__ =='__main__':
    p1 = Process(target=study,args=('任嘉伦',))
    p2 = Process(target=smile,args=('任国超',))
    p1.start()
    p1.join()#添加阻塞主进程
    p2.start()
    p2.join()#添加阻塞主进程
    print('p1的状态是',p1.is_alive())
    print('p2的状态是',p2.is_alive())
# 结果:
# 任嘉伦学习很认真
# 任国超能笑到最后呢
# p1的状态是 False
# p2的状态是 False
3、子进程之间资源不共享
from multiprocessing import Process
import time
li = []  # 全局变量,空列表
def f1():
    for i in range(3):
        li.append(i)
        time.sleep(1)  # 停1s
        print('这是f1中的:',li)
def f2():
    print('这是f2中的:',li)
if __name__=='__main__':
    p1 = Process(target=f1)
    p2 = Process(target=f2)
    p1.start()
    p1.join()
    p2.start()
    p2.join()
# 结果:
# 这是f1中的: [0]
# 这是f1中的: [0, 1]
# 这是f1中的: [0, 1, 2]
# 这是f2中的: [] 
三、进程的通信–队列Queue 1、定义

使用队列Queue实现多进程之间的数据传递

原则:先进先出

  • 入队:将一个数据放到队列的尾部;
  • 出队:从队列的头部取出一个元素
2、常用的方法
  • 初始化Queue()对象 如q = Queue()
  • q.empty() 判断队列是否为空
  • q.get() 到队列中去取值
  • q.put() 把数据放入队列中
  • q.full() 判断这个队列是否是满的
  • q.qsize() 返回队列的大小

例子1:

from queue import Queue
q = Queue(3)   # 最多接收3个数据
# 放数据到队列中
q.put('任嘉伦')
q.put('任国超')
q.put('Allen')
print(q.full())  # True
# 到队列中取值
print(q.get())#任嘉伦
print(q.get())#任国超
print(q.get())#Allen

例子2:

from queue import Queue
q = Queue(3)   # 最多接收3个数据
# 放数据到队列中
q.put('任嘉伦')
q.put('任国超')
print(q.full())  # FALSE,只放了2个数据放到队列
# 到队列中取值
print(q.get())#任嘉伦
print(q.get())#任国超
print(q.get())
3、实现通信

进程1先将数据放入队列中,进程2再去队列中取,队列就相当于一座桥梁;
使用到的方法:

  • 初始化Queue()对象 如q = Queue()
  • q.empty() 判断队列是否为空
  • q.get() 到队列中去取值
  • q.put() 把数据放入队列中
from multiprocessing import Process,Queue
import time
import random
lst = [1,2,3,4]   # 消息数据
# 往队列中放数据
def write(q):
    for i in lst:
        print(f'将{i}放入队列中')
        q.put(i)
        time.sleep(random.random())  # random.random() 表示0-1之间的实数
# 从列队中读(取)数据
def read(q):
    while True:
        if not q.empty(): # 判断队列不为空时
            info = q.get()   # 取值
            print(f'从队列中获取的是{info}')
        else:
            break
if __name__=="__main__":
    # 实例化一个队列
    q  = Queue()
    # 创建子进程
    p1 = Process(target=write,args=(q,))
    p2 = Process(target=read,args=(q,))
    # 启动
    p1.start()
    p1.join()
    p2.start()
    p2.join()
# 结果:
# 将1放入队列中
# 将2放入队列中
# 将3放入队列中
# 将4放入队列中
# 从队列中获取的是1
# 从队列中获取的是2
# 从队列中获取的是3
# 从队列中获取的是4
四、进程池 1、定义

主程序接受的外部任务通过调度算法分到池子内的进程。

2、同步

接完任务后,执行完了,在原地等待,不建议使用

例子:

import time
from multiprocessing import Pool   # 导入进程池
def learn(n):
    print('好好学习,和任嘉伦一样优秀')
    time.sleep(2)
    return n**2
if __name__=="__main__":
    # 定义一个进程池
    p = Pool(3)  # 最大进程数3
    lst = []
    for i in range(6): # i值的范围是0-5
        # 同步方式调用任务
        res = p.apply(learn,args=(i,))  # args 给learn传实参
        lst.append(res)  # 把返回结果添加到列表中
    print(lst)
3、异步

接完任务后,执行完了,执行其他的任务,效率高
用到的方法:

  • p = Pool()
  • p.apply_async()异步非阻塞调用任务
  • p.close() 关闭进程池
  • terminate 终止
  • p.join()阻塞

例子:

import time
from multiprocessing import Pool   # 导入进程池
def learn(n):
    print('好好学习,和任嘉伦一样优秀')
    time.sleep(5)
    return n*2
if __name__=="__main__":
    # 定义一个进程池
    p = Pool(2)  # 最大进程数2
    list = []
    for i in range(6): # i值的范围是0-5
        # 异步方式调用任务
        res = p.apply_async(learn,args=(i,))  # args 给learn传实参
        list.append(res)  # 把返回结果添加到列表中
    p.close() # 关闭进程池,关闭后p不再接收新的任务
    p.join()  # 等待进程池p中所有子进程执行完成,必须放在close()或terminate()之后
    for j in list:
        print(j.get())  # 需要用get方法来获取apply_async返回的结果
# 结果:
# 好好学习,和任嘉伦一样优秀
# 好好学习,和任嘉伦一样优秀
# (中间停留5s)
# 好好学习,和任嘉伦一样优秀
# 好好学习,和任嘉伦一样优秀
# (中间停留5s)
# 好好学习,和任嘉伦一样优秀
# 好好学习,和任嘉伦一样优秀
# 0
# 2
# 4
# 6
# 8
# 10

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/736392.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-28
下一篇 2022-04-28

发表评论

登录后才能评论

评论列表(0条)

保存