|
|
1
365
不管操作系统如何,读取流而不阻塞的可靠方法是使用
|
|
|
2
71
我经常遇到类似的问题;我编写的python程序经常需要能够执行一些主要功能,同时接受来自命令行(stdin)的用户输入。仅仅将用户输入处理功能放在另一个线程中并不能解决问题,因为
在我看来,这比使用select或signal模块来解决这个问题要干净一点,但是它只在unix上工作… |
|
|
3
37
python 3.4引入了新的
provisional API
对于异步IO--
方法类似于
有一个高级接口
如有必要,每个步骤都可以被超时秒限制。 |
|
|
4
20
试试 asyncproc 模块。例如:
模块按照s.lott的建议处理所有线程。 |
|
|
5
17
使用“选择并读取”(1)。
对于readline()-类似:
|
|
|
6
17
你可以很容易地做到这一点
Twisted
. 根据您现有的代码库,这可能不是那么容易使用,但是如果您正在构建一个扭曲的应用程序,那么类似这样的事情就变得几乎微不足道了。你创造了一个
这个 Twisted documentation 有一些很好的信息。 如果您围绕Twisted构建整个应用程序,那么它可以与本地或远程的其他进程进行异步通信,就像这样非常优雅。另一方面,如果你的程序不是建立在Twisted之上的,那么这就没有什么帮助了。希望这对其他读者有帮助,即使它不适用于您的特定应用程序。 |
|
7
8
一种解决方案是让另一个进程执行对该进程的读取,或者使该进程的线程超时。 以下是超时函数的线程版本: http://code.activestate.com/recipes/473878/ 但是,当stdout进入时,您需要读取它吗? 另一种解决方案可能是将输出转储到文件,然后等待进程使用 P.WaIT() .
|
|
|
8
7
免责声明:这只适用于龙卷风 您可以通过将fd设置为非阻塞,然后使用ioloop注册回调来实现这一点。我把这个包装在一个叫 tornado_subprocess 您可以通过pypi安装它:
现在您可以这样做:
您还可以将它与请求处理程序一起使用
|
|
|
9
7
现有的解决方案对我不起作用(详情如下)。最后的工作是使用read(1)实现readline(基于 this answer )后者不会阻止:
现有解决方案不起作用的原因:
|
|
|
10
5
此版本的非阻塞读取 不 需要特殊的模块,并且将在大多数Linux DistOS上工作。
|
|
|
11
3
我添加这个问题来阅读一些子过程。Popen stdout。 以下是我的非阻塞读取解决方案:
|
|
|
12
3
这是我的代码,用于尽快捕获子流程的每个输出,包括部分行。它同时泵送,stdout和stderr的顺序几乎正确。 在python 2.7linux&windows上测试并正确工作。
|
|
|
13
2
在这里添加这个答案,因为它提供了在Windows和Unix上设置非阻塞管道的能力。
所有的
在Unix和Windows系统上都可以使用稍微修改过的版本。
这样,您就可以对Unix和Windows代码使用相同的函数和异常。
为了避免读取不完整的数据,我最后编写了自己的readline生成器(它返回每行的字节字符串)。 它是一个发电机,所以你可以举个例子…
|
|
|
15
1
为什么要打扰线程和队列? 与readline()不同,bufferedreader.read1()不会阻止等待\r\n,如果有任何输出传入,它将尽快返回。
|
|
|
16
0
我创建了一个基于 J. F. Sebastian's solution . 你可以用它。 |
|
|
17
0
根据J.F.Sebastian的答案和其他一些信息来源,我构建了一个简单的子流程管理器。它提供请求非阻塞读取,以及并行运行多个进程。它不使用任何操作系统特定的调用(我知道),因此可以在任何地方工作。
这是Pypi提供的,所以
|
|
|
18
0
编辑:此实现仍然阻塞。使用J.F.Sebastian的 answer 相反。
透过 io module (仅限于2.6),我找到了BufferedReader。这是我的无螺纹无阻塞解决方案。
|
|
|
19
0
我最近偶然发现了同样的问题 我需要一次从流中读取一行(子进程中的尾运行) 在非阻塞模式下 我想避免下一个问题:不烧掉CPU,不按一个字节读取流(就像readline一样),等等。 这是我的实现 https://gist.github.com/grubberr/5501e1a9760c3eab5e0a 它不支持Windows(轮询),不处理EOF, 但它对我很有效 |
|
|
20
0
在我的例子中,我需要一个日志记录模块来捕获后台应用程序的输出并对其进行扩充(添加时间戳、颜色等)。 最后我得到了一个后台线程,它执行实际的I/O操作。下面的代码只适用于POSIX平台。我剥去了不重要的部分。 如果有人打算长期使用这个beast,请考虑管理开放式描述符。就我而言,这不是一个大问题。
|
|
|
21
0
这是在子进程中运行交互式命令的示例,stdout使用伪终端进行交互。您可以参考: https://stackoverflow.com/a/43012138/3555925
|
|
|
22
0
我的问题有点不同,因为我想从正在运行的进程中收集stdout和stderr,但最终还是一样的,因为我想在小部件中呈现生成的输出。 我不想使用队列或其他线程来使用许多建议的解决方法,因为它们不需要执行诸如运行另一个脚本和收集其输出这样的公共任务。
在阅读了建议的解决方案和python文档之后,我通过下面的实现解决了我的问题。是的,它只适用于posix,因为我正在使用
我同意这些文档很混乱,而且对于这样一个常见的脚本任务,实现也很笨拙。我相信旧版本的python有不同的默认值
关键是要设定
错误、调试和详细只是将输出打印到终端的宏。
该解决方案是imho 99.99%有效的,因为它仍然使用阻塞
我欢迎反馈来改进解决方案,因为我对python还是个新手。 |
|
|
23
0
此解决方案使用
考虑到它使用
代码完全符合PEP8。
|
|
|
24
0
我还面临着 Jesse 并用“select”作为 Bradley , Andy 而其他人则是这样做的,只是为了避免繁忙的循环而采用阻塞模式。它使用一个虚拟管道作为假stdin。选择块并等待stdin或管道就绪。当按下某个键时,stdin取消阻止select,并且可以使用read(1)检索键值。当一个不同的线程写入管道时,管道将取消阻塞select,这可以作为stdin需求结束的指示。以下是一些参考代码:
|
|
|
25
-1
我有原始发问者的问题,但不想调用线程。我将Jesse的解决方案与管道中的direct read()和我自己的缓存处理程序混合在一起进行行读取(但是,我的子进程ping总是写满行<一个系统页面大小)。我只在Gobject注册的IO表中阅读,以避免繁忙的等待。现在我通常在Gobject主循环中运行代码以避免线程。
观察者是
主程序设置一个ping,然后调用gobject邮件循环。
任何其他工作都与gobject中的回调有关。 |
|
|
26
-2
下面是一个支持Python中非阻塞读和后台写的模块: https://pypi.python.org/pypi/python-nonblock 提供一个函数, 非块读取,它将从流中读取数据(如果可用),否则返回空字符串(如果流在另一侧关闭,并且所有可能的数据都已读取,则返回无)。 您也可以考虑使用python-subprocess2模块, https://pypi.python.org/pypi/python-subprocess2 它添加到子流程模块中。因此,从“subprocess.popen”返回的对象被添加了一个额外的方法runinbackground。这将启动一个线程,并返回一个对象,该对象将自动填充为向stdout/stderr写入内容,而不会阻塞主线程。 享受! |