【问题标题】:Python application won't exit when using stringIO and pygame.mixer.music.load()使用 stringIO 和 pygame.mixer.music.load() 时 Python 应用程序不会退出
【发布时间】:2012-10-08 23:42:07
【问题描述】:

我正在使用 StringIO 流式传输音乐数据,但是当我使用 pygame.mixer.music.load() 运行时,我的应用程序似乎不会退出。即使我使用 close():

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

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

更多信息。我在从文件打开和使用 stringio 时都做了一个 strace,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()

【问题讨论】:

  • 您是否在resp 对象上调用close()?你是如何退出申请的?
  • 是的,resp.close() 在 song.close() 之前被调用
  • 尝试在您的应用程序关闭之前调用pygame.quit()
  • 你有没有机会在 IDLE 中运行它?
  • 不,我在命令行中运行它。

标签: python pygame stringio


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    我在尝试运行 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。

    【讨论】:

      【解决方案3】:

      我有同样的问题 - 显然 pygame 不擅长自行清理,有时调用 pygame.quit() 会挂起。即使sys.exit() 并没有真正退出,可能是因为pygame.init() 安装了一些错误处理程序。根据#pygame IRC 频道上的人们的说法,这个问题永远不会得到解决,并且 pygame 是一个死项目(!?),尽管邮件列表和项目网站上似乎仍有一些活动。也许这将在 pygame2 中修复...

      【讨论】:

        【解决方案4】:

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

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

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

        我在 Google 上尝试了很多关于以下短语的搜索:pygame quit {fails, hangs,stalls} ...其中大多数引发了与我在此处提供的类似的讨论。

        共识似乎是您希望构建线程来处理“退出”事件,这样所有线程都调用 pygame.quit() 在您的主(父)进程尝试使用 sys.exit() 或干脆退出 __main__ 套件。

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

        【讨论】:

          猜你喜欢
          • 2021-11-16
          • 1970-01-01
          • 1970-01-01
          • 2014-08-16
          • 1970-01-01
          • 1970-01-01
          • 2015-03-31
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多