一、单进程示例

举例一个吃饭活动,有一碗汤和一碗饭,正常操作是一口饭一口汤(当然你先把汤或者饭一口气吃完,当我无话可说)。单进程只能是先吃完饭,再喝汤;或者是先喝完汤,再吃饭。

看代码

import time
def drink():
    for i in range(3):
        print("喝汤……")
        time.sleep(1)

def eat():
    for i in range(3):
        print("吃饭……")
        time.sleep(1)

if __name__ == '__main__':
    eat()
    drink()

运行结果如下

先吃完了所有饭,再喝完所有汤 ,显然这种结果不是我们想要的

二、多进程的实现

进程的创建步骤

1、导入进程包

import multiprocessing

2、通过进程类创建进程对象

进程对象 = multiprocessing.Process(target=*)

此处target的值可以是函数名称 

3、启动进程执行任务

进程对象.start()

看代码示例

import multiprocessing
import time
def drink():
    for i in range(3):
        print("喝汤……")
        time.sleep(1)

def eat():
    for i in range(3):
        print("吃饭……")
        time.sleep(1)

if __name__ == '__main__':
    #target:指定函数名
    drink_process = multiprocessing.Process(target=drink)
    eat_process = multiprocessing.Process(target=eat)

    drink_process.start()
    eat_process.start()

运行结果

 可以看到喝汤和吃饭交叉进行

三、带参多进程

这地方用到的是args和kwargs,其中args是使用元素组的方式给指定任务传参,kwargs是使用字典方式给指定任务传参。

args使用方式

进程对象 = multiprocessing.Process(target=*,args=(*,))

此处注意,若只有一个元素,那个逗号也是不可以省略的

kwargs使用方式

进程对象 = multiprocessing.Process(target=*,kwargs={"变量名": 变量值})

还是以上面吃饭喝汤为例子写代码

import time
import multiprocessing


def eat(num,name):
    for i in range(num):
        print(name+"吃一口……")
        time.sleep(1)


def drink(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,"giao"))
    drink_process = multiprocessing.Process(target=drink,kwargs={"num": 4,"name":"giao"})

    eat_process.start()
    drink_process.start()

执行结果

可以看到参数成功的传入到了所要执行的任务中

四、获取进程的编号

1、获取当前进程的编号

os.getpid()

2、获取当前进程的父进程的编号

os.getppid()

还是以吃饭喝汤为例,看代码

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 drink(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, "giao"))
    drink_process = multiprocessing.Process(target=drink,kwargs={"num": 4, "name":"giao"})
    print("主进程ID:", os.getpid())

    eat_process.start()
    drink_process.start()

结果如图

可以清楚的看到,正常情况下,吃饭和喝汤的父进程是同一个进程,而吃饭和喝汤有不同的进程编号。

进程注意点

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

看代码示例

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("我吃饱了……")

运行结果如图

发现主进程显示已经吃饱了,但是子进程还是在吃,程序等到子进程运行完,才结束。 

2、可以设置子进程守护,当主进程结束时,子进程也不再继续执行,直接结束。

只需要在创建进程之后,加入这样一句代码

进程名称.daemon = True

这样子进程就会守护主进程,主进程结束,子进程也会自动销毁。

看代码

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.daemon = True
    eat_process.start()

    time.sleep(1)
    print("我吃饱了……")

运行结果如图

可以明确看到,主进程结束后,子进程不再继续执行,直接销毁。 

Python的多线程在这

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐