当前位置: 首页 > news >正文

多进程编程

1 多进程概述

进程是正在执行中的应用程序,一个进程包含了该应用程序的所有信息,如加载数据内存空
间、代码、程序数据、对象句柄,执行单元等等,一个应用程序根据其功能的多样性,可以
通过多个进程并发的形式来实现。
计算机中多线程的操作已经可以实现多任务的处理机制了,但是如果涉及到多核 CPU 或者
多个 CPU 的硬件主机,多进程并发编程的实现能比多线程并发机制更加有效的利用和发挥
硬件资源优势。

2 python多进程开发

2.1 multiprocessing

multiprocess常见属性和方法
名称描述
Process进程类型,用于创建和管理进程
LockRLock
Event进程事件类型,用于进程同步
Condition进程条件类型,用于进程同步
Queue进程队列类型,用于多进程数据共享
Manager进程管理类型,用于多进程数据共享
ListenerClient

2.2 多进程的基础操作

import multiprocessing, time, os


def hello_process():
    # 打印信息,展示当前进程编号,父进程编号
    print("hello my name is process", os.getpid(),os.getppid())


if __name__ == "__main__":
    # 创建一个进程
    proc = multiprocessing.Process(target=hello_process)
    proc.start()
    print("hello, i am main:", os.getpid(), os.getppid())

运行程序,查看运行结果
hello ,i am :2456 2772
hello my name is process 13536 2456

2.3 多进程面向对象实现

多进程的面向对象的实现方式类似多线程的操作模式
自定义进程类型,继承系统进程标准类型 multiprocessing.Process
重写父类的 run()方法,在方法中定义执行代码
在使用时创建该自定义进程类型的对象,调用对象的 start()方法启动一个新的进程

import multiprocessing, os


class MyProcess(multiprocessing.Process):

    '''自定义一个进程类型'''
    def run(self):
        '''重写进程处理方法'''
        print("hello, my name is process:", os.getpid(), os.getppid())


if __name__ == "__main__":
    print("hello, my name is main:", os.getpid(), os.getppid())

    # 创建并启动一个进程
    my_proc = MyProcess()
    my_proc.start()

2.4 带参数的多进程:共享?独占?

多线程的操作模式下我们的全局变量是多个线程共享的,所以多线程并发模式下对于数据的
修改非常危险,那么多进程模式下数据的处理应该是什么样的呢?
通过两种方式来观察多进程模式下数据的处理

  • 全局变量的数据
  • 参数数据

    1 全局变量:多进程数据处理
import multiprocessing, time

# 定义全局变量
msg = 3


def chg_numers():
    '''定义处理函数,修改全局变量的值'''
    global msg

    while msg > 0:
        msg -= 1
        print(multiprocessing.current_process().name, " changed : ", msg)


if __name__ == "__main__":
    # 创建两个进程,同时修改数据
    for i in range(2):
        p = multiprocessing.Process(target=chg_numers)
        p.start()

    time.sleep(2)
    print(multiprocessing.current_process().name, msg)

进程本身就是一个独立运行的程序,多进程意味着当前程序被执行了多次,每个进程中全局变量的数据都是互相独立的。

2 参数传递:多进程数据处理
import multiprocessing, time


def chg_numers(msg):
    '''定义处理函数,修改全局变量的值'''

    while msg > 0:
        msg -= 1
        print(multiprocessing.current_process().name, " changed : ", msg)


if __name__ == "__main__":
    # 创建两个进程,同时修改数据
    msg = 3
    for i in range(2):
        p = multiprocessing.Process(target=chg_numers, args=(msg,))
        p.start()

    time.sleep(2)
    print(multiprocessing.current_process().name, msg)

给多进程并发处理函数传递参数的方式,并不能让数据可以被多个进程共享
函数执行并发操作时,每个进程都会单独拷贝一份当前进程的变量数据进行独立使用而不互
相影响,这也是出现上述代码结果的原因

2.5 多进程的简化:内置进程池

多进程的操作在实际应用中也是非常多的,但是纯底层的代码开发控制并发也是一件非常繁
琐的事情,所以就出现了面向过程多进程并发的优化操作方式:进程池 Pool
通过进程池 Pool 可以快速创建多个进程执行指定函数,完成高并发处理操作

1. Pool对象的属性和方法
名称描述
apply(func, args)传递参数 args 并执行函数 func,同时阻塞当前进程直到该函数执行完成,函数 func 只会在进程池中的一个进程中运行
close()Pool 进程池的底层工作机制是向进程池提交任务产生工作进程执行,该方法是主动停止给进程池提交任务,并等待所有提交任务执行完成退出
terminate()立即结束该进程,当进程池对象被回收时自动调用该方法
join()等待工作进程退出,再次之间必须调用 close()或者 teminate

进程池的基本实现

import multiprocessing


def my_process():
    print("hello my name is : ", multiprocessing.current_process().name)


if __name__ == "__main__":
    # 创建一个进程池对象,该进程池可以产生两个处理进程
    pool = multiprocessing.Pool(2)

    # 定义 8 个任务,交给进程池处理
    for i in range(8):
        pool.apply_async(my_process)
    # 停止提交任务
    pool.close()
    # 独占模式:让主线程等待进程池任务执行完成
    pool.join()

可以看到两个进程池产生了两个 工作进程来处理我们的循环的8个任务

多进程下载
有了进程池,可以简单完成一个多进程任务下载的操作处理
该案例只是模拟多进程处理过程,下载任务数据的代码请参考网络数据爬虫技术

import multiprocessing, time


def download(url):
    print(multiprocessing.current_process().name, "开始下载..")
    time.sleep(0.5)
    print(multiprocessing.current_process().name,"下载完成<<")
    time.sleep(2)
    return "下载的数据"


def savedata(data):
    print(multiprocessing.current_process().name,"下载的数据")


if __name__ == "__main__":
    # 创建进程池
    p = multiprocessing.Pool(5)
    # 任务下载循环
    for i in range(20):
        p.apply_async(download, args=("http://www.dy2018.com",), callback=savedata)
    # 停止提交任务
    p.close()
    # 独占
    p.join()

执行时,可以看到20个任务被进程池中的5个进程平均分配进行了处理

2.6 多个进程通信:multiprocessing.Manager

不同线程之间的数据通信,涉及到核心的数据共享问题,主要由PYTHON中提供了内建模块multiprocessing.Manager类型实现

multiprocessing.Manager常见属性和方法
名称描述
Array内置进程间共享数组类型
Queue内置进程间共享队列类型
list()内置进程间共享列表类型
dict()内置进程间共享字典类型
Value内置进程间共享值类型
Barrier进程同步类型
BoundedSemaphore、Semaphore进程信号量类型
LockRLock
Event进程同步事件类型
Condition进程同步条件类型

2.7 多个进程通信:multiprocessing.Queue

多个进程之间的通信操作,数据的传递在PYTHON中的multiprocessing模块中提供了一个专门用于多进程之间进行数据传递的队列:Queue

multiprocessing.Queue 常见属性和方法
名称描述
put(data [, timeout=None])添加一个数据到队列中
put_nowait(data)添加一个数据到队列中,非阻塞模式
get([timeout=None])从队列中获取一个数据
get_nowait()从队列中获取一个数据,非阻塞模式
full()判断队列是否已满
empty()判断队列是否已空
close()关闭队列
qsize()获取队列中的元素数量

2.8 多个进程通信:multiprocessing.Pipe

PYTHON 为了更加友好的多个进程之间的数据通信操作,提供了一个管道类型专门用于进程之间的协作:mulriprocessing.Pipe

multiprocessing.Pipe常见属性和方法
名称描述
init(duplex=True)初始化方法,返回两个数据 conn1,conn2,分别表示管道的两端,默认是双向通信。如果 duplex=False,conn1 只能接受消息,conn2 只能发送消息
send(data)发送消息
recv()接受消息

转载于:https://www.cnblogs.com/chenliang0309/p/9782384.html

相关文章:

  • 实验报告三
  • 跨域获取后台日期-ASP
  • react 的生命周期函数
  • python基础—基本数据类型(int bool str)
  • 【Java】 剑指offer(29) 顺时针打印矩阵
  • 文件上传下载、socketserver(并发)、解读socketserver源码
  • sass笔记
  • 附加数据库时出错问题处理
  • 整理:手机端弹出提示框,使用的bootstrap中的模态框(modal,弹出层),比kendo弹出效果好...
  • Hdoj 1087.Super Jumping! Jumping! Jumping!
  • docker集群演练
  • UVA11090 Going in Cycle!!
  • 继承派生 属性查找
  • 针对shiro框架authc拦截器认证成功后跳转到根目录,而非指定路径问题
  • day06 再谈编码
  • [LeetCode] Wiggle Sort
  • Fabric架构演变之路
  • Java 内存分配及垃圾回收机制初探
  • Javascript基础之Array数组API
  • js面向对象
  • leetcode讲解--894. All Possible Full Binary Trees
  • PHP的类修饰符与访问修饰符
  • PV统计优化设计
  • Solarized Scheme
  • vue脚手架vue-cli
  • 排序算法之--选择排序
  • 前端攻城师
  • 使用权重正则化较少模型过拟合
  • 手机端车牌号码键盘的vue组件
  • 双管齐下,VMware的容器新战略
  • 学习JavaScript数据结构与算法 — 树
  • 一天一个设计模式之JS实现——适配器模式
  • - 转 Ext2.0 form使用实例
  • 《码出高效》学习笔记与书中错误记录
  • 正则表达式-基础知识Review
  • ​​​​​​​GitLab 之 GitLab-Runner 安装,配置与问题汇总
  • !$boo在php中什么意思,php前戏
  • #define与typedef区别
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • ${factoryList }后面有空格不影响
  • (2)Java 简介
  • (floyd+补集) poj 3275
  • (附程序)AD采集中的10种经典软件滤波程序优缺点分析
  • (附源码)ssm捐赠救助系统 毕业设计 060945
  • (三)docker:Dockerfile构建容器运行jar包
  • (学习日记)2024.02.29:UCOSIII第二节
  • (一)基于IDEA的JAVA基础10
  • (转)socket Aio demo
  • (转)德国人的记事本
  • (转)微软牛津计划介绍——屌爆了的自然数据处理解决方案(人脸/语音识别,计算机视觉与语言理解)...
  • *setTimeout实现text输入在用户停顿时才调用事件!*
  • .NET Core 2.1路线图
  • .Net Core webapi RestFul 统一接口数据返回格式
  • .NET Core 和 .NET Framework 中的 MEF2
  • .NET Framework杂记