十、多进程

一、进程基础

冯诺依曼体系:

程序和系统:一个系统一般由多个程序构成。如:Win10系统由进程管理程序、内存管理程序、N个驱动程序等构成。

操作系统的作用:与硬件交互,为用户程序提供安全、稳定的执行环境,提供大量的API供用户程序使用。

任务:打开某个软件、浏览网页、下载电影、听音乐、玩游戏……每个应用程序被称为一个任务。

单任务:只能有一个任务在进行(DOS系统)

多任务:可以有多个任务同时进行(Win10系统)

CPU时间片:程序的执行依赖于CPU,CPU把自己进行时间上的分割,每个程序轮流占用CPU。时间片一般是切换所需时间的100倍。
0.01us 运行 A 0.02us 运行B 时间片轮转

单核: 同一时间,只能有一个程序 在使用CPU

分时操作系统:以时间片轮转的方式,让一台计算机为多个终端服务。 (多用户)

进程:应用程序的动态执行过程。(Process:(为达到某一目标的)过程;进程;流程、过程、步骤;)

  • 网易云音乐 (软件)
  • cloudmusic.exe(进程)
  • 过程: 启动 -> 软件代码要加载到内存--> CPU为进程建立“档案” --> 等CPU时间片 -- > 退出
  • 软件只有运行才能生成进程
  • 1个软件可以生成1~n个进程

二、进程的状态:运行、等待、就绪

  • PCB: 进程控制块(PCB Process Control Block),是操作系统中最重要的记录性数据结构。它是进程管理和控制的最重要的数据结构,每 一个进程均有一个PCB
  • 创建状态:进程在创建时需要申请一个空白PCB,向其中填写控制和管理进程的信息,完成资源分配。如果创建工作无法完成,比如资源无 法满足,就无法被调度运行,把此时进程所处状态称为创建状态
  • 就绪状态:Ready to run。创建进程后,进程进入就绪状态(即进程被加载到主内存中)这里的进程已经准备好运行,正在等待获取执行它的CPU时间。准备由CPU执行的进程在队列中维护以备处理。
  • 执行状态:进程由CPU选择执行,进程中的指令由任何一个可用的CPU核心执行。
  • 阻塞状态:每当进程请求访问I/O或需要用户输入,它将进入阻塞或等待状态。进程继续在主内存中等待,不需要CPU。一旦I/O操作完成,进程将进入就绪状态。
  • 终止状态:进程被终止,PCB也被删除。

操作系统管理进程:分配内存给进程,分配CPU时间片给进程,存储进程信息(使用PID标识进程,为进程设置优先级,记录进程状态,记录I/O状态等

如何人为地改变进程的状态:可以通过信号修改进程的状态。taskkill /f /PID 8899 taskkill /f /t /im Typora.exe 杀程序

三、创建并执行进程

在Python中,执行一个Python脚本,就会创建一个进程。

可以用os.getpid()获得进程的PID

如何创建2个进程? multiprocessing.Process创建进程

关于daemon:

  • 设置daemon = True,主进程执行完,不会等待该进程
  • 设置daemon = False,主进程执行完,会等待该进程执行完再退出

关于join:

  • p1.json()
  • 主进程会等p1执行完再执行剩下的代码。
import os
import time
from multiprocessing import Process


def cloudmusic():
    """模拟网易云音乐的进程"""
    for i in range(5):
        print(f"子进程{os.getpid()}正则播放 无人之岛...")
        time.sleep(1)


def lol():
    """模拟lol进程"""
    for i in range(8):
        print(f"子进程{os.getpid()}游戏中,请勿打扰...")
        time.sleep(1)


def process_test():
    start_time = time.time()
    # 创建网易云音乐进程
    # 在主进程中通过Process类创建的进程对象就是子进程
    p1 = Process(target=cloudmusic)
    p2 = Process(target=lol)
    # 设置daemon = True,主进程执行完,不会等待该进程
    # 设置daemon = False,主进程执行完,会等待该进程执行完再退出
    p1.daemon = True
    p2.daemon = False
    print(f"我是主进程,我的进程id是{os.getpid()}")
    p1.start()  # 启动子进程p1
    p2.start()  # 启动子进程p2
    p1.join()
    # p2.join()
    end_time = time.time()
    print(end_time - start_time)  # 这是主进程中最后1行代码,运行完,主进程结束


if __name__ == '__main__':
    process_test()
    # start_time = time.time()
    # lol()
    # cloudmusic()
    # end_time = time.time()
    # print(end_time - start_time)

四、进程的全局变量

每创建一个进程,CPU都会单独分配资源

所以,多个进程不会共享全局变量

from multiprocessing import Process

result = 0


def work01():
    global result
    result += 1
    print(f'work01中result值是{result}')


def work02():
    global result
    result += 1
    print(f'work02中result值是{result}')


def main():
    work01()
    work02()
    print(result)


def process_test():
    p1 = Process(target=work01)
    p2 = Process(target=work02)
    p1.start()
    p2.start()
    p1.join()
    p2.join()


if __name__ == '__main__':
    process_test()
    print(f'主进程中result的值是:{result}')

'''
work01中result值是1
work02中result值是1
主进程中result的值是:0
'''

五、多进程中使用队列共享数据

多进程中如何使用队列共享数据?

答: 多个进程共享主进程中创建的队列即可。主进程创建队列,然后把队列当做参数传给每个子进程即可。

from multiprocessing import Process, Queue


def work01(q):
    print(id(q))
    r = q.get()
    r += 1
    q.put(r)
    print(f'work01中q值是{r}')


def work02(q):
    print(id(q))
    r = q.get()
    r += 1
    q.put(r)
    print(f'work02中q值是{r}')


def process_test():
    q = Queue()
    q.put(0)
    p1 = Process(target=work01, args=(q,))
    p2 = Process(target=work02, args=(q,))
    p1.start()
    p2.start()
    p1.join()
    p2.join()
    print(f'主进程中q的值是:{q.get()}')


if __name__ == '__main__':
    process_test()

 六、自定义进程类

import multiprocessing
import time


class MyProcess(multiprocessing.Process):
    def __init__(self,user):
        super(MyProcess, self).__init__()
        self.user = user


    def run(self):
        """进程启动的时候会调用此方法"""
        for i in range(3):
            time.sleep(1)
            print(f'{self.user}正在学习Python...')


if __name__ == '__main__':
    p1 = MyProcess(user='小样儿')
    p2 = MyProcess(user='乐乐')
    p1.start()
    p2.start()

'''
小样儿正在学习Python...
乐乐正在学习Python...
小样儿正在学习Python...
乐乐正在学习Python...
小样儿正在学习Python...
乐乐正在学习Python...
'''
原文地址:https://www.cnblogs.com/zhangjx2457/p/14129476.html