python多进程程序设计 之一

python多进程程序设计 之一

multiprocessing

multiprocessing 是一个python模块,它使用类似于线程模块的 API生成进程。multiprocessing模块提供本地和远程并行运行,通过使用子进程代替线程,有效地回避python全局解释器锁。因此,多处理模块允许程序员充分利用给定机器上的多个处理器。

multiprocessing模块还引入了线程模块中没有API。一个典型的例子是 Pool 对象,它提供了一种方便的方法,跨多个输入值并行执行函数,跨进程分配输入数据(数据并行性)。

Process类

在 multiprocessing中,通过创建Process对象,然后调用其 start() 方法来生成进程。

产生进程

根据平台的不同,多处理支持三种启动进程的方式。这些启动方法是

  • spawn, 父进程启动一个新的Python解释器进程。子进程只会继承运行进程对象的 run() 方法所需的资源。特别是,来自父进程的,不必要的文件描述符和句柄将不会被继承。与使用 fork 或 forkserver 相比,使用此方法启动进程相当慢。
  • fork, 父进程使用 os.fork() 来 fork Python 解释器。子进程在启动时实际上与父进程相同。父进程的所有资源都被子进程继承。
  • forkserver, 当程序选择 forkserver 启动方法时,会生成一个服务器进程。从那时起,每当需要新进程时,父进程就会连接到服务器并请求它派生一个新进程。 fork 服务器进程是单线程的,除非系统库或预加载的imports产生线程的副作用,因此使用 os.fork() 通常是安全的。不会继承不必要的资源。

在 POSIX 上,使用spawn或forkserver启动方法还将启动一个资源跟踪器进程,该进程跟踪由程序进程创建的未链接的命名系统资源(例如,命名信号量或SharedMemory对象)。当所有进程退出后,资源跟踪器将取消任何剩余跟踪对象的链接。通常应该没有这样的对象,但如果进程被信号杀死,则可能会出现一些"泄漏"资源。

set_start_method()启动

在主模块的 if name == 'main' 子句中,使用 set_start_method() 。

from multiprocessing import *

def subproc():
    print("subprocess")

if __name__ == '__main__':
    set_start_method('spawn')
    p = Process(target=subproc)
    p.start()
    p.join()

显示器输出

javascript 复制代码
subprocess
get_context()启动

使用 get_context() 来获取上下文对象。上下文对象具有与multiprocessing模块相同的 API,并允许在同一程序中多次使用启动方法。

from multiprocessing import *

def subproc():
    print("subprocess")

if __name__ == '__main__':
    print("call get_context...")
    ctx = get_context('spawn')
    p = ctx.Process(target=subproc)
    p.start()
    p.join()

显示器输出

javascript 复制代码
call get_context...
subprocess

成员函数

构造函数

multiprocessing.Process(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)

Process对象表示在单独流程中运行的活动。

  • group,应始终为None。
  • target, 是由 run() 方法调用的可调用对象。它默认为 None,这意味着什么都不被调用。
  • name, 是进程名称。
  • args,是目标调用的参数元组。
  • kwargs, 是目标调用的关键字参数的字典。
  • daemon,如果提供,daemon参数将进程的daemon标志设置为 True 或 False。如果 None (默认),该标志将从创建进程继承。

默认情况下,没有参数传递给target。 args 参数默认为 (),可用于指定要传递给target的参数列表或元组。

如果子类重写构造函数,则它必须确保,在对进程执行任何其他操作之前,调用基类构造函数 (Process.init())。

run/start

词法: run()

Process类的成员函数run()表示进程的活动。

在子类中可以重载这个函数。标准run()函数调用可调用对象target,target是作为参数target传递给构造函数。如果该构造函数包含可调用对象target,则构造器的参数args 和 kwargs,将作为参数,传递给可调用对象target。

词法:start()

Process类的成员函数start()启动进程的活动。

每个进程对象最多只能调用一次。它在单独的进程中,调用对象的 run() 方法。

join

词法: join([timeout])

  • 如果可选参数 timeout为None (默认值),则该函数将阻塞,直到调用 join() 函数的进程终止。
  • 如果 timeout 是正数,则最多阻塞 timeout 秒。如果该函数的进程终止,或该函数超时,则该函数将返回 None。检查进程的退出代码,以确定它是否终止。

一个进程可以多次调用join。

进程无法join自身,因为这会导致死锁。在进程启动之前,调用join是错误的。

应用实列

实列说明

该实列使用两种不同的方法产生进程的活动

  • Consumer子进程使用构造函数
  • Producer子进程使用进程子类run()成员函数。在__init__(self,...)中,必须调用super(Producer,self).init()初始化基类的初始化函数。
  • Producer子进程使用进程子类的参数传递方法更方便,灵活。

实列代码

from multiprocessing import *

def Consumer(v1, v2, v3, width):
    print("Consumer v1:{0} v2:{1} v3: {2} width: {3}".format(v1, v2, v3, width))

class Producer(Process):
    def __init__(self, args, keys):
        super(Producer,self).__init__()
        self.args = args;
        self.keys = keys;
        
    def run(self):
        print("Producer args: {0}".format(self.args))
        print("Producer keys: {0}".format(self.keys))
    
if __name__ == '__main__':
    print("call get_context...")
    ctx = get_context('spawn')
    args = [1, 2, 3]
    keys = {"width":"12"}
    
    p1 = ctx.Process(target=Consumer, args=args, kwargs=keys)
    p2 = Producer(args, keys);

    p1.start()
    p2.start()
    
    p1.join()
    p2.join()
    
    print("Consumer exit code:{0}".format(p1.exitcode))
    print("Producer exit code:{0}".format(p2.exitcode))

显示器输出

call get_context...
Consumer v1:1 v2:2 v3: 3 width: 12
Producer args: [1, 2, 3]
Producer keys: {'width': '12'}
Consumer exit code:0
Producer exit code:0
相关推荐
小码的头发丝、25 分钟前
Django中ListView 和 DetailView类的区别
数据库·python·django
Chef_Chen1 小时前
从0开始机器学习--Day17--神经网络反向传播作业
python·神经网络·机器学习
千澜空2 小时前
celery在django项目中实现并发任务和定时任务
python·django·celery·定时任务·异步任务
斯凯利.瑞恩2 小时前
Python决策树、随机森林、朴素贝叶斯、KNN(K-最近邻居)分类分析银行拉新活动挖掘潜在贷款客户附数据代码
python·决策树·随机森林
yannan201903132 小时前
【算法】(Python)动态规划
python·算法·动态规划
蒙娜丽宁2 小时前
《Python OpenCV从菜鸟到高手》——零基础进阶,开启图像处理与计算机视觉的大门!
python·opencv·计算机视觉
光芒再现dev2 小时前
已解决,部署GPTSoVITS报错‘AsyncRequest‘ object has no attribute ‘_json_response_data‘
运维·python·gpt·语言模型·自然语言处理
好喜欢吃红柚子2 小时前
万字长文解读空间、通道注意力机制机制和超详细代码逐行分析(SE,CBAM,SGE,CA,ECA,TA)
人工智能·pytorch·python·计算机视觉·cnn
小馒头学python2 小时前
机器学习是什么?AIGC又是什么?机器学习与AIGC未来科技的双引擎
人工智能·python·机器学习
神奇夜光杯3 小时前
Python酷库之旅-第三方库Pandas(202)
开发语言·人工智能·python·excel·pandas·标准库及第三方库·学习与成长