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
相关推荐
三体世界12 小时前
测试用例全解析:从入门到精通(1)
linux·c语言·c++·python·功能测试·测试用例·测试覆盖率
Python私教12 小时前
Django全栈班v1.04 Python基础语法 20250912 下午
后端·python·django
xchenhao13 小时前
Scikit-Learn 对糖尿病数据集(回归任务)进行全面分析
python·机器学习·回归·数据集·scikit-learn·特征·svm
xchenhao13 小时前
Scikit-learn 对加州房价数据集(回归任务)进行全面分析
python·决策树·机器学习·回归·数据集·scikit-learn·knn
这里有鱼汤13 小时前
发现一个高性能回测框架,Python + Rust,比 backtrader 快 250 倍?小团队必备!
后端·python
☼←安于亥时→❦13 小时前
数据分析之Pandas入门小结
python·pandas
带娃的IT创业者13 小时前
《Python Web部署应知应会》No3:Flask网站的性能优化和实时监测深度实战
前端·python·flask
赴33513 小时前
图像拼接案例,抠图案例
人工智能·python·计算机视觉
TwoAI13 小时前
Scikit-learn 机器学习:构建、训练与评估预测模型
python·机器学习·scikit-learn
max50060013 小时前
OpenSTL PredRNNv2 模型复现与自定义数据集训练
开发语言·人工智能·python·深度学习·算法