【发布时间】:2013-04-09 07:42:50
【问题描述】:
现状
我正在写 a small Python program 以在您的终端中播放来自 8tracks 的播放列表。
它由三部分组成,一个使用stdlib的cmd模块的client.py,一个使用python-requests访问API的api.py模块和一个在从模式下创建mplayer子进程的player.py模块和向它发送命令。
问题
到目前为止,这有效,问题是除了轮询子进程的标准输出之外,我没有其他方法可以判断歌曲是否已在 mplayer 中播放完毕。这意味着我必须观看该过程,以便在歌曲播放完毕后请求并开始播放列表中的下一首歌曲。
问题是等待子进程会阻塞cmd 模块的主循环。不过,我也不能简单地在单独的线程或进程中运行它,因为我必须共享对子进程的 stdout 的引用,而像这样的引用不能在进程之间共享。
可能的方法
我为此想到了不同的解决方案。我可以将player.py 放在一个单独的进程中并通过队列发送文本命令,但这会使事情变得过于复杂。我可以创建一个 Twisted 应用程序,但 Twisted 相当大,我不知道从哪里开始。另外,我不希望在我的项目中有这样的依赖。
第三种解决方案是使用 Gevent。问题是我如何让它与cmd 模块一起工作。据我了解 Gevent,我将不得不在我“等待”某事的每个地方屈服。在这种情况下,这将是在 HTTP 请求期间、在 cmd.cmdloop() 期间等待以及在子进程轮询之间的暂停期间。但是如何让cmd 模块屈服?某种子类或猴子补丁?
【问题讨论】:
-
为什么你更喜欢“在你的项目中没有这样的依赖”?到底什么是“这种依赖”?依赖 Gevent 或 Python 与依赖 Twisted 有何不同?
-
只是我认为 Twisted 是一个“巨大的项目”,我不太了解,仅此而已。但我并不完全反对它,只要它在我的情况下工作而不重写我所有的代码:)
-
为什么不能只有一个命令输出尾线程?在进程之间共享 fds 很棘手,但在线程之间这应该是可行的。
-
@fmoo 嗯,到目前为止我只试过
multiprocessing.dummy(它使用线程),它不能做这样的事情。但也许我应该尝试直接使用Threading... -
您能否发布一些(简化的?)
player.py的代码?过去,我完全将子进程尾部拆分为自己的线程,没有问题。multiprocessing.dummy应该也能正常工作。
标签: python parallel-processing subprocess twisted gevent