Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Python多处理为pygame准备图像_Python_Multithreading_Pygame_Python Multiprocessing_Pygame Surface - Fatal编程技术网

如何使用Python多处理为pygame准备图像

如何使用Python多处理为pygame准备图像,python,multithreading,pygame,python-multiprocessing,pygame-surface,Python,Multithreading,Pygame,Python Multiprocessing,Pygame Surface,我正在制作一个幻灯片应用程序,它有一个非常小的平移和缩放效果。我在用pygame 因此,主显示器是实时30fps+,我不希望它在加载新图像时出现口吃-这需要1/30秒的时间 所以我想使用一些并行进程来准备图像,并向主进程提供这些对象,这些对象是类的实例 我尝试了线程和多进程。线程'工作',但它仍然跳跃(我责备)-整个事情减慢时,线程忙!因此,代码运行了,但没有达到允许连续平滑显示的目标 但是,多进程segfaults(pygame降落伞)只要我对从主进程接收到的准备好的图像调用一个方法。我尝试过

我正在制作一个幻灯片应用程序,它有一个非常小的平移和缩放效果。我在用pygame

因此,主显示器是实时30fps+,我不希望它在加载新图像时出现口吃-这需要1/30秒的时间

所以我想使用一些并行进程来准备图像,并向主进程提供这些对象,这些对象是类的实例

我尝试了线程和多进程。线程'工作',但它仍然跳跃(我责备)-整个事情减慢时,线程忙!因此,代码运行了,但没有达到允许连续平滑显示的目标

但是,多进程segfaults
(pygame降落伞)
只要我对从主进程接收到的准备好的图像调用一个方法。我尝试过管道通信和队列通信-两者都会导致相同的问题。该方法一直运行,直到调用

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)时,我得到:

('do','/path/to/a.jpg')
(‘收到’,)
('do','/path/to/b.jpg')
致命Python错误:(pygame降落伞)分段错误
zsh:中止(堆芯转储)

我使用多处理解决了这个问题,方法是让Img类将图像加载到存储在属性中的字符串缓冲区中,然后添加一个
postReceive
方法,将图像加载到存储在image属性中的曲面中

父进程从子进程接收到
Img
对象后,调用
postReceive
方法

因此,子对象创建的对象不绑定到任何pygame-y

    self.imageBuffer = pygame.image.tostring(
      pygame.transform.scale(image, (640,480)),
      'RGB')
然后,
Img
中的新方法简单如下:

def: postReceive(self):
    self.image = pygame.image.frombuffer( self.imagebuffer, 'RGB' )
在此处添加对此的调用:

    # collect image ready-prepared by other process
    if self.parent_conn.poll():
        self.img = self.parent_conn.recv().postReceive()
        print ("received ", self.img)

一个简短的可编译示例会有所帮助(如果可能的话)。不管怎样:你是如何发送图像的,你能把它序列化然后发送吗?这可能是内存问题(线程是共享内存的,多进程不是)。@isset谢谢,请看编辑的Q。我也尝试过酸洗,但我得到了一个“Surface Can Can Pickle”错误。嘿,所以我遇到了一个非常类似的解决方案,在另一个进程中将图像加载到字符串缓冲区,然后将该缓冲区发送到openGL上下文所在的主进程。我认为这就是为什么之前会发生崩溃的原因,您试图从主进程外部访问openGL上下文。您说这个解决方案适合您,但在主进程中调用pygame.image.frombuffer()时,我仍然会有轻微的口吃,因为这是一个将缓冲区复制到视频内存的阻塞调用。好奇你是否见过口吃等等?我遗漏了什么特别的东西?ThxSo我所做的是使用并行进程打开图像,并将其缩小到父进程所需的最大大小。这样,我的缓冲区相对较小,加载速度较快。
    # collect image ready-prepared by other process
    if self.parent_conn.poll():
        self.img = self.parent_conn.recv().postReceive()
        print ("received ", self.img)