我正在制作一个带有非常顽皮的平移和缩放效果的幻灯片应用程序。我正在使用pygame。
因此,主显示器是实时 30fps+,我不希望它在加载新图像时出现卡顿——这需要超过 1/30 秒。
所以我想使用一些并行的过程来准备图像并用这些对象提供主进程,这些对象是一个类的实例。
我尝试过线程和多进程。线程“工作”,但它仍然跳动(我责怪python) - 当线程忙时,整个事情都会变慢!所以代码运行了,但它没有达到允许持续平滑显示的目标。
但是,一旦我对从主进程接收到的准备好的图像调用方法,多进程就会出现段错误。(pygame parachute)
我已经尝试过管道和队列通信——两者都会导致同样的问题。该方法一直运行直到它调用
sized = pygame.transform.scale(self.image, newsize )
然后是段错误。此类与主进程没有任何依赖关系。
pygame 不喜欢多处理吗?还有其他兼容的方式吗?有没有办法“很好”的辅助线程可能会停止线程方法的执行?
非常感谢任何帮助。很高兴发布更多代码,只是在评论中询问,但除非需要,否则不想在这里倾倒一个大列表。
提前致谢!
编辑
这是我能做到的尽可能短的。您需要在底部的构造函数中提供三个 jpeg 文件的路径。
#!/usr/bin/env python2
import pygame
import sys
import time
import re
import os
import pickle
from random import randrange, shuffle
from multiprocessing import Process, Pipe
import Queue
class Img:
"""The image objects I need to pass around"""
def __init__(self, filename=None):
image = pygame.image.load(filename).convert()
self.image = pygame.transform.scale(image, (640,480))
def getSurface(self):
"""Get a surface, blit our image onto it in right place."""
surface = pygame.Surface((640,480))
# xxx this next command fails
sized = pygame.transform.scale(self.image, (640,480))
surface.blit(sized, (0,0))
return surface
class Floaty:
"""demo"""
def __init__(self, fileList):
self.fileList = fileList
pygame.init()
self.screen = pygame.display.set_mode((640,480))
# open the first image to get it going
self.img = Img(self.fileList.pop())
# Set up parallel process for opening images
self.parent_conn, child_conn = Pipe()
self.feeder = Process(target=asyncPrep, args=(child_conn,))
self.feeder.start()
def draw(self):
"""draw the image"""
# collect image ready-prepared by other process
if self.parent_conn.poll():
self.img = self.parent_conn.recv()
print ("received ", self.img)
# request new image
self.parent_conn.send(self.fileList.pop())
self.screen.blit(self.img.getSurface(), (0, 0))
pygame.display.flip()
def asyncPrep(conn):
"""load up the files"""
while True:
if conn.poll(1):
filename = conn.recv()
print ("doing ", filename)
img = Img(filename)
conn.send(img)
if __name__ == '__main__':
fileList = ['/path/to/a.jpg', 'path/to/b.jpg', 'path/to/c.jpg']
f = Floaty(fileList)
clock = pygame.time.Clock()
while 1:
f.draw()
clock.tick(4);
当我运行这个(Python 2.7.6)时,我得到:
('doing ', '/path/to/a.jpg')
('received ', <__main__.Img instance at 0x7f2dbde2ce60>)
('doing ', '/path/to/b.jpg')
Fatal Python error: (pygame parachute) Segmentation Fault
zsh: abort (core dumped)