multiprocessing模块介绍

【一】multiprocessing模块介绍

  • python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程。

    • Python提供了multiprocessing。
    • multiprocessing模块用来开启子进程,并在子进程中执行我们定制的任务(比如函数),该模块与多线程模块threading的编程接口类似。
  • multiprocessing模块的功能众多:

    • 支持子进程、通信和共享数据、执行不同形式的同步
    • 提供了Process、Queue、Pipe、Lock等组件。
  • 需要再次强调的一点是:

    • 与线程不同,进程没有任何共享状
    • 进程修改的数据,改动仅限于该进程内。

【二】Process类介绍

p = multiprocessing.Process()

def __init__(self, group=None, target=None, name=None, args=(), kwargs={},
         *, daemon=None):
# group : 参数表示一个组,但是我们不用
# target: 目标进程,表示调用的对象 要让子进程完成的任务
# name 当前子进程的名称
# args : 按照位置传参的参数(元组)
# kwargs :按照关键字传参的参数(字典)
# daemon: 守护进程

【三】Process类的对象的方法介绍

p = multiprocessing.Process()
# p 是实例后的对象
# 【1】p.start()
# 启动进程,并且会调用进程中 的 p.run()
# target:需要执行的子进程任务

self._target = target
def run(self):
    '''
    Method to be run in sub-process; can be overridden in sub-class
    '''
    if self._target:
        self._target(*self._args, **self._kwargs)
# 【2】p.run()
# 启动自己的 run 方法,执行当前子进程函数
# 进程运行时的方法
# 真正的调用 自己传入的进程方法
  • p.terminate():

    • 强制终止进程p,不会进行任何清理操作
    • 如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。
    • 如果p还保存了一个锁那么也将不会被释放,进而导致死锁.
  • p.is_alive():

    • 如果p仍然运行,返回True
  • p.join([timeout]):

    • 主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。
    • timeout是可选的超时时间
    • 需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程

【四】Process类的对象属性介绍

  • p.daemon

    • 默认值为False
    • 如果设为True,代表p为后台运行的守护进程
    • 当p的父进程终止时,p也随之终止
    • 并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置
  • p.name:

    • 获取当前子进程的名称
  • p.pid

    • 获取当前子进程的pid(进程号)
  • p.exitcode:

    • 进程在运行时为None、如果为–N,表示被信号N结束(了解即可)
  • p.authkey

    • 进程的身份验证键,默认是由os.urandom()随机生成的32字符的字符串。
    • 这个键的用途是为涉及网络连接的底层进程间通信提供安全性,这类连接只有在具有相同的身份验证键时才能成功(了解即可)
  • p.exitcode:

    • 获取当前子进程的父进程的进程号

【1】Process 对象方法

import random
import multiprocessing
import os
import time
from multiprocessing import current_process


def work(name):
    print(
        f"{name} is starting ... pid is {current_process().pid}... os_pid is {os.getpid()}... os_ppid is {os.getppid()}")
    sleep_time = random.randint(1, 6)
    print(f"{name} is starting sleeping {sleep_time} seconds...")
    time.sleep(sleep_time)
    print(f"{name} is ending sleeping {sleep_time} seconds...")
    print(
        f"{name} is ending ... pid is {current_process().pid}... os_pid is {os.getpid()}... os_ppid is {os.getppid()}")


def main():
    # 创建一个子进程
    task_list = []
    for i in range(0, 5):
        task = multiprocessing.Process(target=work,  # args = (f'task_{i}')
                                       kwargs={'name': f'task_{i}'})
        task.start()
        print('terminate before ...', task.is_alive())
        # 临时杀死
        task.terminate()
        task_list.append(task)
    # 启动子线程
    for task in task_list:
        task.join()
        print('terminate after ...', task.is_alive())  # 帮我们将当前子进程杀死


if __name__ == '__main__':
    print(
        f"main process is starting ... pid is {current_process().pid} ... os_pid is {os.getpid()} ... os_ppid is {os.getppid()}")
    start_time = time.time()
    main()
    end_time = time.time()
    print(
        f"main process is ending ... pid is {current_process().pid} ... os_pid is {os.getpid()} ... os_ppid is {os.getppid()}")


# main process is starting ... pid is 7280 ... os_pid is 7280 ... os_ppid is 16464
# terminate before ... True
# terminate before ... True
# terminate before ... True
# terminate before ... True
# terminate before ... True
# terminate after ... False
# terminate after ... False
# terminate after ... False
# terminate after ... False
# terminate after ... False
# main process is ending ... pid is 7280 ... os_pid is 7280 ... os_ppid is 16464

	# 【一】查看当前进程的进程ID
    # 【1】进程ID : 指的是某个应用程序运行在系统之上的标志
    # 【2】查看所有进程  win : cmd ---> tasklist / mac linux ---> 打开终端 ---> pas aux
    # 【3】过滤端口 : win : cmd ---> tasklist|findstr PORT/PID  / mac linux ---> 打开终端 ---> pas aux|grep PORT/PID
    # 【4】在代码中查看进程ID
    # (1)from multiprocessing import current_process
    # (2)获取当前进程的PID
    # current_process().pid == os.getpid()
    # (3)查看当前进程的父ID
    # os.getppid()
    # 【二】杀死子线程
    # task.terminate()
    # 【三】查看当前线程或进程是够存活
    # task.is_alive()
posted @ 2024-05-23 20:51  光头大炮  阅读(64)  评论(0编辑  收藏  举报