Я делаю приложение для слайд-шоу с эффектом панорамирования и масштабирования. Я использую пигейм.
Таким образом, основной дисплей работает со скоростью 30 кадров в секунду в реальном времени, и я не хочу, чтобы он зависал, когда ему нужно загрузить новое изображение — это занимает более 1/30 секунды.
Поэтому я хотел использовать какой-то параллельный процесс для подготовки изображений и подачи в основной процесс этих объектов, которые являются экземплярами класса.
Я пробовал использовать threading и многопроцессорность. Многопоточность «работает», но все еще дергается (я виню python) - все это тормозит, когда поток занят! Таким образом, код работал, но он не соответствовал цели обеспечения непрерывного плавного отображения.
Но многопроцессорный segfaults (pygame parachute)
, как только я вызываю метод на полученном подготовленном образе из основного процесса. Я пробовал связь по каналам и очередям - оба приводят к одной и той же проблеме. Метод работает до тех пор, пока не вызовет
sized = pygame.transform.scale(self.image, newsize )
Тогда есть segfault. Этот класс не имеет никаких зависимостей от основного процесса.
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)