使用stringIO和pygame.mixer.music.load()时,Python应用程序不会退出

时间:2012-10-18 13:33:20

标签: python pygame stringio

我正在使用StringIO来传输音乐数据,但是当我使用pygame.mixer.music.load()运行时,我的应用程序将无法退出。即使我使用close():

def PlaySong(self, song_id):
    song = StringIO.StringIO(resp.read())
    self.pygame.mixer.music.load(song)
    ....

该函数将返回,但必须杀死该应用程序。如果我将响应保存到文件,然后加载文件名,它将关闭。有人可以帮忙吗?我不想使用本地存储。

更多信息。我对文件中的两个打开都做了一个strace,并且使用stringio,strace将正确退出两个实例。这些线条看起来很干净。

工作代码:

def playsong():
    mp3 = "/home/adam/Documents/pinyin/pinyinchart_win/pinyin/zuo2.mp3"
    #with open(mp3, "rb") as outfile:
    #    song = outfile.read()

    #io = StringIO.StringIO(song)
    pygame.init()
    pygame.mixer.music.load(mp3)
    pygame.mixer.music.play()
    while pygame.mixer.music.get_busy():
        pygame.time.Clock().tick(50)

    #io.close()
    #outfile.close()

不工作代码:

def playsong():
    mp3 = "/home/adam/Documents/pinyin/pinyinchart_win/pinyin/zuo2.mp3"
    with open(mp3, "rb") as outfile:
        song = outfile.read()

    io = StringIO.StringIO(song)
    pygame.init()
    #pygame.mixer.music.load(io)
    pygame.mixer.music.load(mp3)
    pygame.mixer.music.play()
    while pygame.mixer.music.get_busy():
        pygame.time.Clock().tick(50)

    io.close()
    outfile.close()

4 个答案:

答案 0 :(得分:0)

尝试使用sys.exit()和内置函数exit()。

答案 1 :(得分:0)

我在尝试运行pykaraoke时经常遇到这个问题;我今晚才跟踪它到pygame.mixer.music.play()。奇怪的是,它只发生在多处理器系统上;如果我在单处理器系统上进行测试,或者使用“maxcpus = 1”启动Linux,则不会发生。否则,硬挂起会定期发生,我必须使用SIGKILL,因为SIGTERM不起作用。

所以我认为这是pygame中的一个错误,或者它依赖的东西。我刚刚向pygame-users邮件列表发送了一个Python脚本和非常短的(50k)MP3文件;如果发生任何事情,我会报告回来。

更新:我能够使用与SDL_mixer直接交互的程序重现该错误。答案是,这是smpeg中的一个错误。重建SDL_mixer并支持libmad打开。你还必须完全卸载smpeg,因为SDL_mixer会尝试使用它而支持libmad。

答案 2 :(得分:0)

我有同样的问题 - 显然pygame在自己清理之后非常糟糕,并且调用pygame.quit()有时只是挂起。即使sys.exit()实际上没有退出,也许是因为pygame.init()安装了一些错误处理程序。据#pygame IRC频道上的人说,这个问题永远不会被修复,而pygame是一个死的项目(!?),尽管邮件列表和项目网站上似乎仍有一些活动。也许这将在pygame2中修复......

答案 3 :(得分:0)

当使用Python的线程支持时,我已经看到过这种行为。 pygame可能正在使用线程,并且其中一些是隐式生成的,未标记为“守护程序”线程,并且在您尝试 .quit()时未加入。

请注意, sys.exit()不太可能正常工作,因为它会抛出SystemExit异常(可能会被捕获,特别是可能由 atexit 处理程序捕获)。此外, sys.exit()只会退出处理它的线程,其他线程仍将运行。 (StackOverflow: Issue with sys.exit() in pygame了解更多详情。)

这是另一个:StackOverflow: pygame screen freezes when I close it

我尝试了一些关于短语的谷歌搜索:pygame quit {failed,hangs,stalls} ......其中大部分引发了与我在这里提供的类似的讨论。

共识似乎是你要构造你的线程来处理一个“退出”事件,这样所有人都会在你的主(父)进程尝试之前调用 pygame.quit()使用 sys.exit()或简单地退出 _ _main_ _ 套件。

除此之外,我还会检查您的音乐设备上是否有某些进程,线程或驱动程序停滞不前。在类Unix系统中,将在进程列表(ps命令输出)中显示为处于“D”状态。 (我假设,你提到 strace 你在Linux上运行)。