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)


相关文章
|
4天前
|
分布式计算 MaxCompute 对象存储
|
2月前
|
并行计算 数据处理 调度
Python中的并发编程:探索多线程与多进程的奥秘####
本文深入探讨了Python中并发编程的两种主要方式——多线程与多进程,通过对比分析它们的工作原理、适用场景及性能差异,揭示了在不同应用需求下如何合理选择并发模型。文章首先简述了并发编程的基本概念,随后详细阐述了Python中多线程与多进程的实现机制,包括GIL(全局解释器锁)对多线程的影响以及多进程的独立内存空间特性。最后,通过实例演示了如何在Python项目中有效利用多线程和多进程提升程序性能。 ####
|
2月前
|
调度 iOS开发 MacOS
python多进程一文够了!!!
本文介绍了高效编程中的多任务原理及其在Python中的实现。主要内容包括多任务的概念、单核和多核CPU的多任务实现、并发与并行的区别、多任务的实现方式(多进程、多线程、协程等)。详细讲解了进程的概念、使用方法、全局变量在多个子进程中的共享问题、启动大量子进程的方法、进程间通信(队列、字典、列表共享)、生产者消费者模型的实现,以及一个实际案例——抓取斗图网站的图片。通过这些内容,读者可以深入理解多任务编程的原理和实践技巧。
109 1
|
3月前
|
Python
Python中的多线程与多进程
本文将探讨Python中多线程和多进程的基本概念、使用场景以及实现方式。通过对比分析,我们将了解何时使用多线程或多进程更为合适,并提供一些实用的代码示例来帮助读者更好地理解这两种并发编程技术。
|
2月前
|
监控 JavaScript 前端开发
python中的线程和进程(一文带你了解)
欢迎来到瑞雨溪的博客,这里是一位热爱JavaScript和Vue的大一学生分享技术心得的地方。如果你从我的文章中有所收获,欢迎关注我,我将持续更新更多优质内容,你的支持是我前进的动力!🎉🎉🎉
30 0
|
3月前
|
存储 C++ Python
[oeasy]python037_ print函数参数_sep分隔符_separator
本文介绍了Python中`print`函数的`sep`参数,即分隔符。通过回顾上文内容,解释了类型与`type`的概念,并强调了参数类型的重要性。文章详细探讨了`print`函数如何使用`sep`参数来分隔输出值,默认分隔符为空格(序号32)。还讨论了如何修改分隔符为其他字符,如冒号,并解释了为何反斜杠需要使用双反斜杠表示。最后,文章追溯了`sep`名称的由来,以及相关词汇的历史背景,如盎格鲁-萨克逊人的武器和语言。
99 0
|
7月前
|
监控 Linux 应用服务中间件
探索Linux中的`ps`命令:进程监控与分析的利器
探索Linux中的`ps`命令:进程监控与分析的利器
146 13
|
6月前
|
运维 关系型数据库 MySQL
掌握taskset:优化你的Linux进程,提升系统性能
在多核处理器成为现代计算标准的今天,运维人员和性能调优人员面临着如何有效利用这些处理能力的挑战。优化进程运行的位置不仅可以提高性能,还能更好地管理和分配系统资源。 其中,taskset命令是一个强大的工具,它允许管理员将进程绑定到特定的CPU核心,减少上下文切换的开销,从而提升整体效率。
掌握taskset:优化你的Linux进程,提升系统性能
|
6月前
|
弹性计算 Linux 区块链
Linux系统CPU异常占用(minerd 、tplink等挖矿进程)
Linux系统CPU异常占用(minerd 、tplink等挖矿进程)
202 4
Linux系统CPU异常占用(minerd 、tplink等挖矿进程)
|
5月前
|
算法 Linux 调度
探索进程调度:Linux内核中的完全公平调度器
【8月更文挑战第2天】在操作系统的心脏——内核中,进程调度算法扮演着至关重要的角色。本文将深入探讨Linux内核中的完全公平调度器(Completely Fair Scheduler, CFS),一个旨在提供公平时间分配给所有进程的调度器。我们将通过代码示例,理解CFS如何管理运行队列、选择下一个运行进程以及如何对实时负载进行响应。文章将揭示CFS的设计哲学,并展示其如何在现代多任务计算环境中实现高效的资源分配。