python多进程

1 导入进程包

#导入进程包
import multiprocessing

 

2. Process进程类的说明

Process([group [, target [, name [, args [, kwargs]]]]])

  • group:指定进程组,目前只能使用None
  • target:执行的目标任务名
  • name:进程名字
  • args:以元组方式给执行任务传参
  • kwargs:以字典方式给执行任务传参

Process创建的实例对象的常用方法:

  • start():启动子进程实例(创建子进程)
  • join():等待子进程执行结束
  • terminate():不管任务是否完成,立即终止子进程

Process创建的实例对象的常用属性:

name:当前进程的别名,默认为Process-N,N为从1开始递增的整数

3. 多进程完成多任务的代码

import multiprocessing
import time

def dance():
    for i in range(5):
        print("跳舞中。。。")
        time.sleep(0.2)


def sing():
    for i in range(5):
        print("唱歌中。。。")
        time.sleep(0.2)

if __name__ == '__main__':
    # 创建跳舞的子进程
    # group: 表示进程组,目前只能使用None
    # target: 表示执行的目标任务名(函数名、方法名)
    # name: 进程名称, 默认是Process-1, .....
    dance_process = multiprocessing.Process(target=dance)
    sing_process = multiprocessing.Process(target=sing)

    # 启动子进程
    dance_process.start()
    sing_process.start()

执行结果:

跳舞中。。。
唱歌中。。。
跳舞中。。。
唱歌中。。。
跳舞中。。。
唱歌中。。。
跳舞中。。。
唱歌中。。。
跳舞中。。。
唱歌中。。。

Process finished with exit code 0

4.获取当前进程编号

os.getpid() 表示获取当前进程编号

import multiprocessing
import time
import os

def dance():
    # 获取当前进程编号
    print("dance:", os.getpid())
    # 获取当前进程
    print("dance:", multiprocessing.current_process())
    for i in range(5):
        print("跳舞中。。。")
        time.sleep(0.2)


def sing():
    # 获取当前进程编号
    print("sing:", os.getpid())
    # 获取当前进程
    print("sing:", multiprocessing.current_process())
    for i in range(5):
        print("唱歌中。。。")
        time.sleep(0.2)

if __name__ == '__main__':
    # 获取当前进程编号
    print("main:", os.getpid())
    # 获取当前进程
    print("main:", multiprocessing.current_process())
    # 创建跳舞的子进程
    # group: 表示进程组,目前只能使用None
    # target: 表示执行的目标任务名(函数名、方法名)
    # name: 进程名称, 默认是Process-1, .....
    dance_process = multiprocessing.Process(target=dance)
    sing_process = multiprocessing.Process(target=sing)

    # 启动子进程
    dance_process.start()
    sing_process.start()

执行结果:

main: 9300
main: <_MainProcess name='MainProcess' parent=None started>
dance: 11336
dance: <Process name='Process-1' parent=9300 started>
跳舞中。。。
sing: 12928
sing: <Process name='Process-2' parent=9300 started>
唱歌中。。。
跳舞中。。。
唱歌中。。。
跳舞中。。。
唱歌中。。。
跳舞中。。。
唱歌中。。。
跳舞中。。。
唱歌中。。。

Process finished with exit code 0

5. 获取当前进程的父进程编号

os.getppid() 表示获取当前父进程编号

import multiprocessing
import time
import os

def dance():
    # 获取当前进程编号
    print("dance:", os.getpid())
    # 获取当前进程
    print("dance:", multiprocessing.current_process())
    # 获取父进程编号
    print("dance_ppid:", os.getppid())


def sing():
    # 获取当前进程编号
    print("sing:", os.getpid())
    # 获取当前进程
    print("sing:", multiprocessing.current_process())
    # 获取父进程编号
    print("sing_ppid:", os.getppid())

if __name__ == '__main__':
    # 获取当前进程编号
    print("main:", os.getpid())
    # 获取当前进程
    print("main:", multiprocessing.current_process())

    # 获取父进程编号
    print("main_ppid:", os.getppid())
    # 创建跳舞的子进程
    # group: 表示进程组,目前只能使用None
    # target: 表示执行的目标任务名(函数名、方法名)
    # name: 进程名称, 默认是Process-1, .....
    dance_process = multiprocessing.Process(target=dance)
    sing_process = multiprocessing.Process(target=sing)

    # 启动子进程
    dance_process.start()
    sing_process.start()

执行结果:

main: 14304
main: <_MainProcess name='MainProcess' parent=None started>
main_ppid: 2628
dance: 11004
dance: <Process name='Process-1' parent=14304 started>
sing: 11456
sing: <Process name='Process-2' parent=14304 started>
dance_ppid: 14304
sing_ppid: 14304

Process finished with exit code 0

6. 子进程参数传递

6.1 通过args以元组形式传递,参数顺序需要和任务需要参数对应

import multiprocessing
import time
import os

def dance(count):
    for i in range(count):
        print("跳舞中...")


if __name__ == '__main__':
    # args通过元组传递参数
    dance_process = multiprocessing.Process(target=dance, args=(3,))

    # 启动子进程
    dance_process.start()

执行结果:

跳舞中...
跳舞中...
跳舞中...

Process finished with exit code 0

6.2 通过kwargs以字典方式传递参数

# args通过元组传递参数
    dance_process = multiprocessing.Process(target=dance, kwargs={"count": 3})

7. 进程之间不共享全局变量

import multiprocessing
import time
import os

global_list = []

def process1():
    global_list.append(1)
    global_list.append(2)
    print("process1", global_list)

def process2():
    print("process2", global_list)


if __name__ == '__main__':
    # args通过元组传递参数
    p1 = multiprocessing.Process(target=process1)
    p2 = multiprocessing.Process(target=process2)

    # 启动子进程
    p1.start()
    p2.start()

    print("main:", global_list)

执行结果:

main: []
process1 [1, 2]
process2 []

Process finished with exit code 0

进程之间不共享全局变量的解释效果图:

 

说明:

  • 创建子进程会对主进程资源进行拷贝,也就是说子进程是主进程的一个副本,好比是一对双胞胎,之所以进程之间不共享全局变量,是因为操作的不是同一个进程里面的全局变量,只不过不同进程里面的全局变量名字相同而已。

8. 主进程会等待所有的子进程执行结束再结束

import multiprocessing
import time
import os


def dance():
    for i in range(10):
        print("dance...")
        time.sleep(0.2)

if __name__ == '__main__':
    # args通过元组传递参数
    p1 = multiprocessing.Process(target=dance)

    # 启动子进程
    p1.start()
    time.sleep(0.5)
    exit()

执行结果:

dance...
dance...
dance...
dance...
dance...
dance...
dance...
dance...
dance...
dance...

Process finished with exit code 0

说明:子进程中循环执行全部完成后程序才停止,说明主线程等待子进程执行结束后才结束

9. 设置守护主进程:

子进程可以设置为守护主进程,主进程退出子进程直接销毁,子进程的生命周期依赖与主进程
import multiprocessing
import time
import os


def dance():
    for i in range(10):
        print("dance...")
        time.sleep(0.2)

if __name__ == '__main__':
    # args通过元组传递参数
    p1 = multiprocessing.Process(target=dance)

    # 设置守护主进程,主进程退出子进程直接销毁,子进程的生命周期依赖与主进程
    p1.daemon = True

    # 启动子进程
    p1.start()
    time.sleep(0.5)
    exit()

执行结果:

dance...
dance...

Process finished with exit code 0

说明:主进程结束前会销毁子进程,而不是等待其执行完

10.直接销毁子进程

import multiprocessing
import time
import os


def dance():
    for i in range(10):
        print("dance...")
        time.sleep(0.2)

if __name__ == '__main__':
    # args通过元组传递参数
    p1 = multiprocessing.Process(target=dance)

    # 启动子进程
    p1.start()
    time.sleep(0.5)

    # 直接销毁子进程
    p1.terminate()

    exit()

执行结果:

dance...
dance...

Process finished with exit code 0

10. 通过进程编号杀死进程

os.kill(pid, 9)
import multiprocessing
import time
import os


def dance():
    pid = os.getpid()
    for i in range(10):
        print("dance...")
        time.sleep(0.2)
        os.kill(pid, 9)

if __name__ == '__main__':
    # args通过元组传递参数
    p1 = multiprocessing.Process(target=dance)

    # 启动子进程
    p1.start()
    time.sleep(0.5)

    exit()

执行结果:

dance...

Process finished with exit code 0

11. 进程等待 

p1.join()   # 会等待p1进程执行结束再执行后续代码

说明:p1为创建的进程对象

import multiprocessing
import time
import os

glob_list = []

def dance():
    for i in range(10):
        print("dance...")
        time.sleep(0.2)

if __name__ == '__main__':
    # args通过元组传递参数
    p1 = multiprocessing.Process(target=dance)

    # 启动子进程
    p1.start()
    time.sleep(0.5)
    print("here")

执行结果:

dance...
dance...
here
dance...
dance...
dance...
dance...
dance...
dance...
dance...
dance...

Process finished with exit code 0

添加线程等待后:

import multiprocessing
import time
import os

glob_list = []

def dance():
    for i in range(10):
        print("dance...")
        time.sleep(0.2)

if __name__ == '__main__':
    # args通过元组传递参数
    p1 = multiprocessing.Process(target=dance)

    # 启动子进程
    p1.start()
    time.sleep(0.5)
    p1.join()   # 会等待p1进程执行结束再执行后续代码
    print("here")

执行结果:

dance...
dance...
dance...
dance...
dance...
dance...
dance...
dance...
dance...
dance...
here

Process finished with exit code 0

 

posted @ 2021-01-03 19:04  foreast  阅读(188)  评论(0编辑  收藏  举报