• 「Python入门」Python多进程



    活动地址:CSDN21天学习挑战赛


    前言

    本文主要介绍python单进程多进程。Python 要进行多进程操作,需要用到muiltprocessing库,其中的Process类跟threading模块的Thread类很相似。
    进程是指一个程序在给定数据集合上的一次执行过程,是系统进行资源分配和运行调用的独立单位。可以简单地理解为操作系统中正在执行的程序。也就说,每个应用程序都有一个自己的进程。
    每一个进程启动时都会最先产生一个线程,即主线程。然后主线程会再创建其他的子线程。python的多进程性能要明显优于多线程,因为cpythonGIL对性能做了约束。

    在这里插入图片描述


    一、 单进程

    以吃饭睡觉打豆豆为例。单进程需要先吃饭,在睡觉,最后打豆豆,次序不可打乱。

    # 单进程
    import time
    def eat():
        for i in range(3):
            print("吃饭……")
            time.sleep(1)
     
    def sleep():
        for i in range(3):
            print("睡觉……")
            time.sleep(1)
    
    def play():
        for i in range(3):
            print("打豆豆……")
            time.sleep(1)
     
    if __name__ == '__main__':
        eat()
        sleep()
        play()
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    在这里插入图片描述

    二、 多进程

    以吃饭睡觉打豆豆为例。多进程对吃饭,睡觉,打豆豆,可以交叉进行,无需按序执行。

    # 多进程
    import multiprocessing # 导入进程包
    import time
    def eat():
        for i in range(3):
            print("吃饭……")
            time.sleep(1)
     
    def sleep():
        for i in range(3):
            print("睡觉……")
            time.sleep(1)
    
    def play():
        for i in range(3):
            print("打豆豆……")
            time.sleep(1)
     
    if __name__ == '__main__':
        #target:指定函数名
        eat_process = multiprocessing.Process(target=eat) # 通过进程类创建进程对象
        sleep_process = multiprocessing.Process(target=sleep)
        play_process = multiprocessing.Process(target=play)
     
        eat_process.start()
        sleep_process.start()
        play_process.start()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    在这里插入图片描述

    三、 带参多进程

    • target:指定执行的函数名。此处注意,若只有一个元素,那个逗号也是不可以省略的。
    • args:使用元组方式给指定任务传参
    • kwargs:使用字典方式给指定任务传参
    # 带参多进程
    import time
    import multiprocessing
     
     
    def eat(num,name):
        for i in range(num):
            print(name+"吃饭……")
            time.sleep(1)
     
    def sleep(num,name):
        for i in range(num):
            print(name+"睡觉……")
            time.sleep(1)
    
    def play(num,name):
        for i in range(num):
            print(name+"打豆豆……")
            time.sleep(1)
     
     
    if __name__ == '__main__':
        # target:指定执行的函数名。此处注意,若只有一个元素,那个逗号也是不可以省略的。
        # args:使用元组方式给指定任务传参
        # kwargs:使用字典方式给指定任务传参
        eat_process = multiprocessing.Process(target=eat,args=(3,'vitian')) # 通过进程类创建进程对象
        sleep_process = multiprocessing.Process(target=sleep,args=(3,'anna'))
        play_process = multiprocessing.Process(target=play,args=(3,'prince'))
     
        eat_process.start()
        sleep_process.start()
        play_process.start()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    在这里插入图片描述

    四、 获取进程的编号

    以吃饭睡觉打豆豆为例。主进程相同,子进程各不同。

    # 获取进程的编号
    import time
    import multiprocessing
    import os
     
     
    def eat(num,name):
        print("吃饭的进程ID:", os.getpid())
        print("吃饭的主进程ID:", os.getppid())
        for i in range(num):
            print(name+"吃饭……")
            time.sleep(1)
     
     
    def sleep(num,name):
        print("睡觉的进程ID:", os.getpid())
        print("睡觉的主进程ID:", os.getppid())
        for i in range(num):
            print(name+"睡觉……")
            time.sleep(1)
    
    def play(num,name):
        print("打豆豆的进程ID:", os.getpid())
        print("打豆豆的主进程ID:", os.getppid())
        for i in range(num):
            print(name+"打豆豆……")
            time.sleep(1)
     
    if __name__ == '__main__':
        # target:指定执行的函数名
        # args:使用元组方式给指定任务传参
        # kwargs:使用字典方式给指定任务传参
        eat_process = multiprocessing.Process(target=eat,args=(3,'vitian')) # 通过进程类创建进程对象
        sleep_process = multiprocessing.Process(target=sleep,kwargs={"num": 2, "name":"anna"})
        play_process = multiprocessing.Process(target=play,args=(1,'prince'))
        print("主进程ID:", os.getpid())
     
        eat_process.start()
        sleep_process.start()
        play_process.start()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    在这里插入图片描述

    五、 主进程会等待所有的子进程执行结束再结束

    # 主进程会等待所有的子进程执行结束再结束
    import multiprocessing
    import time
     
     
    def eat():
        for i in range(10):
            print("吃饭睡觉打豆豆……")
            time.sleep(0.5)
     
     
    if __name__ == '__main__':
        eat_process = multiprocessing.Process(target=eat)
        eat_process.start()
     
        time.sleep(1)
        print("主进程结束了……")
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述

    六、 子进程守护

    设置子进程守护,当主进程结束时,子进程也不再继续执行,直接结束。
    在这里插入图片描述

    七、 多线程与单线程的取舍

    多线程在IO密集型的操作下似乎也没有很大的优势(IO操作的任务再繁重一些就能体现出优势),在CPU密集型的操作下明显地比单线程线性执行性能更差,但是对于网络请求这种忙等阻塞线程的操作,多线程的优势便非常显著了。
    多进程无论是在CPU密集型还是IO密集型以及网络请求密集型(经常发生线程阻塞的操作)中,都能体现出性能的优势。不过在类似网络请求密集型的操作上,与多线程相差无几,但却更占用CPU等资源,所以对于这种情况下,我们可以选择多线程来执行。

  • 相关阅读:
    Semantic Kernel 入门系列:💬Semantic Function
    【微服务】微服务常见概念
    数据分析方法:RFM模型
    【Unity】Xml的加密读取保存
    10个好用的Mac数据恢复软件推荐—恢复率高达99%
    【Designing ML Systems】第 7 章 :模型部署和预测服务
    『德不孤』Pytest框架 — 7、Pytest预期失败
    剑指offer 24. 合并两个排序的链表
    Go语言入门记录:从channel的池应用、sync的Pool、benchmark、反射reflect、json处理、http、性能分析和一些编程习惯
    ubuntu16.04部署nginx(无网络)
  • 原文地址:https://blog.csdn.net/qq_38209578/article/details/126153238