繁体   English   中英

Python子进程Popen.terminate()仍然停留在wait()

[英]Python subprocess Popen.terminate() still stuck on wait()

我正在尝试使用RPi实现一个无线电播放器。 目标是设置播放列表并在填充播放列表后开始播放。 一旦执行停止代码,播放器和无线电进程将退出。

无线电过程很好地终止,但即使在呼叫终止后,播放器进程仍然处于等待状态。 如果再次调用停止代码,则播放器进程终止

事情尝试:

  1. 重新排序等待命令(播放器,收音机)/(收音机,播放器)
  2. 类似地重新排序终止命令
  3. 使用kill而不是terminate会挂起RPi

玩家代码:

while playlist:
    player = subprocess.Popen(
            ["avconv", "-i", "Music/%s" % playlist[0], "-f", "s16le", "-ar", 
            "22.05k", "-ac", "1", "-"], stdout=subprocess.PIPE)

    radio = subprocess.Popen(["./pifm", "-", freq], stdin=player.stdout)

    radio.wait()
    print "************ exiting from radio :)"
    player.wait()
    print "************ exiting from player :)"

    playlist.pop(0)
player = None
radio = None

播放器停止代码(从另一个线程调用):

print "************ stop requested"

if radio and radio.poll() is None:
    print "************ terminating radio :)"
    radio.terminate()

if player and player.poll() is None:
    print "************ terminating player :)"
    player.terminate()

替代方案:

另一种选择是为播放器提供无线电和按需处理的持久接收器

def start_radio():
    global radio
    radio = subprocess.Popen(["./pifm"...], stdin=subprocess.PIPE)

def play():
    global player
    while playlist and radio:
        player = subprocess.Popen(["avconv"...], stdout=radio.stdin)
        player.wait()
        playlist.pop(0)

def stop():
   if player and player.poll() is None:
      print "************ terminating player :)"
      player.terminate()

但在这种情况下,调用player.terminate()会关闭播放器,同时在无线电过程中重复播放最后一个数据包(如卡住的记录)。 这个卡住的记录播放,直到我开始一个新的播放器或终止收音机。

正如@JFSebastian所提到的,使用player.stdout.close()可以正常工作。 整个代码库在这里发布https://github.com/hex007/pifm_server

所以最终的代码看起来像这样

while playlist:
    player = subprocess.Popen(
            ["avconv", "-i", "Music/%s" % playlist[0], "-f", "s16le", "-ar", 
            "22.05k", "-ac", "1", "-"], stdout=subprocess.PIPE)

    radio = subprocess.Popen(["./pifm", "-", freq], stdin=player.stdout)

    player.stdout.close()

    radio.wait()
    player.wait()

    if stop_requested:
        stop_requested = False
        break

    playlist.pop(0)

player = None
radio = None

和停止代码:

stop_requested = True

if radio and radio.poll() is None:
    radio.terminate()

if player and player.poll() is None:
    player.terminate()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM