我正在使用 python 2.7.14,目前正在尝试使用多处理模块同时在 pygame 屏幕的两侧进行绘制(2 个线程从单个 pygame 屏幕调用函数),但每次我从屏幕调用函数时(例如screen.get_width())都会引发以下错误:
screen.get_width()
Process Process-1: Traceback (most recent call last): File "C:\Python27\lib\multiprocessing\process.py", line 267, in _bootstrap self.run() File "C:\Python27\lib\multiprocessing\process.py", line 114, in run self._target(*self._args, **self._kwargs) File "C:\Python27\multiplayer.py", line 9, in single_core_game print screen.get_width() error: display Surface quit
我知道通过线程写入并不是最优雅的方式,因此我很高兴听到其他选择。
在 Python 中使用 multiprocessing 时遇到这种错误,通常是因为 Pygame 的 Surface(例如屏幕对象)无法在多个进程间共享。Pygame 初始化的显示窗口和相关对象属于主进程,不能在子进程中直接使用。
multiprocessing
Surface
解决这个问题的一种方法是:让所有的图形更新和渲染操作都在主进程中进行,而子进程只负责计算或其他任务,然后通过队列或管道等机制与主进程通信。这样你就可以保持绘图操作的单线程,而同时进行多进程的计算任务。
你可以像下面这样调整你的代码:
import pygame import multiprocessing import time # 初始化Pygame pygame.init() # 创建屏幕 screen = pygame.display.set_mode((800, 600)) def draw_on_side(queue, side): """这个函数将绘制内容发送给主进程""" while True: if side == 'left': color = (255, 0, 0) # 红色 else: color = (0, 255, 0) # 绿色 queue.put(color) # 将颜色信息发送到主进程 time.sleep(1) def main(): queue = multiprocessing.Queue() # 启动两个子进程 process_left = multiprocessing.Process(target=draw_on_side, args=(queue, 'left')) process_right = multiprocessing.Process(target=draw_on_side, args=(queue, 'right')) process_left.start() process_right.start() # 游戏循环 running = True while running: screen.fill((0, 0, 0)) # 清空屏幕 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # 从队列获取绘制信息并更新屏幕 if not queue.empty(): color = queue.get() if color == (255, 0, 0): # 红色代表左侧 pygame.draw.rect(screen, color, pygame.Rect(0, 0, 400, 600)) # 左侧画红色 elif color == (0, 255, 0): # 绿色代表右侧 pygame.draw.rect(screen, color, pygame.Rect(400, 0, 400, 600)) # 右侧画绿色 pygame.display.flip() # 更新屏幕 process_left.terminate() process_right.terminate() pygame.quit() if __name__ == "__main__": main()
screen
draw_on_side
multiprocessing.Queue
这种方法避免了多进程共享 Pygame 对象的问题,同时也保留了多进程的计算优势。