Python 多进程以及进程共享参数

简介: 这段时间在做一款游戏的挂机软件,我发现进入游戏后的逻辑和判断人物死亡的逻辑需要同时进行(因为不知道什么时候就暴毙了),以前我习惯用线程来进行同步,但是我发现由于我的代码中的逻辑比较复杂,且有多个嵌套的无限循环会导致线程阻塞,所以我决定用进程的方式来实现同步运行。

前言

这段时间在做一款游戏的挂机软件,我发现进入游戏后的逻辑和判断人物死亡的逻辑需要同时进行(因为不知道什么时候就暴毙了),以前我习惯用线程来进行同步,但是我发现由于我的代码中的逻辑比较复杂,且有多个嵌套的无限循环会导致线程阻塞,所以我决定用进程的方式来实现同步运行。

进程的概念 multiprocessing

在 Python 中进程是一个独立的运行环境,有自己的内存空间,系统资源和执行状态,你可以给他理解成一个房子,在一段 Python 代码被执行的时候,其实 Python 解释器也会创建一个进程来执行该脚本中的代码,当我们在这个代码中使用多进程的时候,其实是创建了一个子进程去执行代码,而这个脚本的进程则为父进程(相当于生了个孩子)

线程与进程的区别 threading

线程是一个进程中的执行路径,他可以在一个进程中存在多个,且共享进程之间的内存空间和资源,但是他不能并发执行(因为 Python 存在 GIL),而是当 A 线程 不占用资源后,再去执行 B 线程的这样交替执行(对于 IO 操作来说 还是可以进行并发执行的)

为什么采用进程而不用线程

我这里为什么要采用进程而不用线程,因为我主要使用的是 opencv 来识别图片与特征点的,而 opencv 是 CPU 密集型操作,所以对于线程来说,他无法实现并发行执行。

示例代码与解释

结束了上面的“废话”,开始撸代码

创建进程

    import multiprocessing

    def test():
        print("子进程")

    if __name__ == "__main__":
        process = multiprocessing.Process(target=test,args(,))
        print("父进程")
        Process.start()
        process.join()

我们可以看到 创建进程的写法其实是和创建线程差不多的

错误处理

    try:
        process = multiprocessing.Process(target=test,args(,))
        print("父进程")
        process.start()
        process.join()
    except KeyboardInterrupt:
        print("Received KeyboardInterrupt, terminating the process...")
        process.terminate()  # 立即终止所有子进程
    else:
        process.close()  # 关闭进程池,不再接受新的任务
    finally:
        process.join()  # 等待所有子进程退出
        print("所有子进程退出")

进程间共享变量

由于每个进程都开辟了独立的内存空间,所以说他们之间的变量是无法共享的,上面我们说了 执行.py 文件是启动了一个新的 Python 解释器也是开启一个进程,我们进程中的变量和内存空间都是共享的,比如函数中引用的 global 变量 也属于是共享的其实,进程中也提供的办法可以来在不同进程中共享变量,只不过不像是 global 那样了,且根据不同的变量形式划分的了不同的写法

基本数据类型

    shared_val = multiprocessing.Value('i', 0)  # 'i' 表示整数
    shared_val = multiprocessing.Value('b', True)  # 'b' 表示布尔值
    shared_val = multiprocessing.Value('d', 0.0) # d 表示浮点数

我们可以推测出 i 表示整数 是因为 int 是 整数类型 b 表示布尔值 是因为 bool 是 布尔类型 d 表示浮点数 是因为 float 是 浮点类型

数组

PS:这里需要提前引入 ctypes 模块

    shared_array = 10
    # 初始化共享数组
    for i in range(array_size):
        shared_array[i] = i

    shared_array = multiprocessing.Array(ctypes.c_int, array_size)
    # 创建进程
    process = multiprocessing.Process(target=test, args=(shared_array,))

取值

    def test(shared_array):
        print(shared_array[0])
        shared_array[0] = 10

字典

字典我们需要用到 Manager 对象

    # 创建 manager 对象
    manager = multiprocessing.Manager()
    # 创建一个共享字典
    shared_dict = manager.dict()
    # 初始化字典
    shared_dict['a'] = 1
    # 创建进程
    process = multiprocessing.Process(target=test, args=(shared_dict,))

取值

    def test(shared_dict):
        print(shared_dict['a'])
        shared_dict['a'] = 10

队列

队列我们需要用到 Manager 对象 PS:这里需要提前引入 ctypes 模块

    # 创建 manager 对象
    manager = multiprocessing.Manager()
    # 创建一个共享队列
    shared_queue = manager.Queue()
    # 初始化队列
    shared_queue.put(1)
    # 创建进程
    process = multiprocessing.Process(target=test, args=(shared_queue,))

取值

    def test(shared_queue):
        print(shared_queue.get())
        shared_queue.put(10)


相关文章
|
2天前
|
负载均衡 Java 调度
探索Python的并发编程:线程与进程的比较与应用
本文旨在深入探讨Python中的并发编程,重点比较线程与进程的异同、适用场景及实现方法。通过分析GIL对线程并发的影响,以及进程间通信的成本,我们将揭示何时选择线程或进程更为合理。同时,文章将提供实用的代码示例,帮助读者更好地理解并运用这些概念,以提升多任务处理的效率和性能。
|
11天前
|
监控 Ubuntu API
Python脚本监控Ubuntu系统进程内存的实现方式
通过这种方法,我们可以很容易地监控Ubuntu系统中进程的内存使用情况,对于性能分析和资源管理具有很大的帮助。这只是 `psutil`库功能的冰山一角,`psutil`还能够提供更多关于系统和进程的详细信息,强烈推荐进一步探索这个强大的库。
26 1
|
14天前
|
Python
惊!Python进程间通信IPC,让你的程序秒变社交达人,信息畅通无阻
【9月更文挑战第13天】在编程的世界中,进程间通信(IPC)如同一场精彩的社交舞会,每个进程通过优雅的IPC机制交换信息,协同工作。本文将带你探索Python中的IPC奥秘,了解它是如何让程序实现无缝信息交流的。IPC如同隐形桥梁,连接各进程,使其跨越边界自由沟通。Python提供了多种IPC机制,如管道、队列、共享内存及套接字,适用于不同场景。通过一个简单的队列示例,我们将展示如何使用`multiprocessing.Queue`实现进程间通信,使程序如同社交达人般高效互动。掌握IPC,让你的程序在编程舞台上大放异彩。
13 3
|
2天前
|
存储 算法 Java
关于python3的一些理解(装饰器、垃圾回收、进程线程协程、全局解释器锁等)
该文章深入探讨了Python3中的多个重要概念,包括装饰器的工作原理、垃圾回收机制、进程与线程的区别及全局解释器锁(GIL)的影响等,并提供了详细的解释与示例代码。
9 0
|
2天前
|
调度 Python
python3多进程实战(python3经典编程案例)
该文章提供了Python3中使用多进程的实战案例,展示了如何通过Python的标准库`multiprocessing`来创建和管理进程,以实现并发任务的执行。
12 0
|
5天前
|
并行计算 API 调度
探索Python中的并发编程:线程与进程的对比分析
【9月更文挑战第21天】本文深入探讨了Python中并发编程的核心概念,通过直观的代码示例和清晰的逻辑推理,引导读者理解线程与进程在解决并发问题时的不同应用场景。我们将从基础理论出发,逐步过渡到实际案例分析,旨在揭示Python并发模型的内在机制,并比较它们在执行效率、资源占用和适用场景方面的差异。文章不仅适合初学者构建并发编程的基础认识,同时也为有经验的开发者提供深度思考的视角。
|
1天前
|
数据采集 人工智能 数据挖掘
Python编程入门:从基础到实战的快速指南
【9月更文挑战第25天】本文旨在为初学者提供一个简明扼要的Python编程入门指南。通过介绍Python的基本概念、语法规则以及实际案例分析,帮助读者迅速掌握Python编程的核心技能。文章将避免使用复杂的专业术语,而是采用通俗易懂的语言和直观的例子来阐述概念,确保内容的可读性和实用性。
|
1天前
|
机器学习/深度学习 人工智能 数据挖掘
探索Python编程之美:从基础到进阶
【9月更文挑战第25天】在数字时代的浪潮中,编程已成为一项宝贵的技能。本篇文章将引导你步入Python的奇妙世界,一个既适合初学者又深受资深开发者喜爱的编程语言。我们将一起揭开Python语言的基础面纱,探索它的核心概念,并通过实际示例深入理解其强大功能。无论你是编程新手还是希望提升自己的老手,这篇文章都将为你提供一条清晰的学习路径,助你在编程之旅上更进一步。
|
1天前
|
存储 开发者 Python
从理论到实践:Python中Trie树与Suffix Tree的完美结合,开启编程新篇章!
在编程领域,高效的数据结构对于解决问题至关重要。本文通过一个案例分析,介绍如何在Python中结合使用Trie树(前缀树)和Suffix Tree(后缀树)。案例聚焦于开发具备高效拼写检查和文本相似度检测功能的文本编辑器。首先,通过构建Trie树快速检查单词是否存在;接着,利用Suffix Tree检测文本相似度。尽管Python标准库未直接提供Suffix Tree,但可通过第三方库或自定义实现。本文展示了高级数据结构在实际应用中的强大功能,并强调了理论与实践相结合的重要性。
7 1
|
1天前
|
数据挖掘 Python
Python数据挖掘编程基础
本章介绍了Python数据挖掘编程的基础知识,涵盖Python入门所需的命令、判断与循环、函数、库导入等内容,并重点讲解了数据分析预处理和建模常用库。通过学习基本运算、数据结构、字符串操作等,帮助读者快速掌握Python语言,为后续数据挖掘工作打下坚实基础。例如,通过代码`a=3`进行赋值,利用`a*3`执行乘法运算,使用`a**3`计算幂,以及通过对字符串的拼接和分割操作,展示Python的强大功能。
8 0