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