- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
下面的代码在Win7中运行,有线程T1和T2,T1在原窗口中打印dir内容,T2在新窗口中ping 4秒。
import os
import sys
import logging
import subprocess
import threading
class T1 (threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
proc = subprocess.Popen("dir", shell=True, stdout=subprocess.PIPE)
for line in iter(proc.stdout.readline, ''):
logging.debug(line)
logging.info("HEREEEEEEEE")
class T2 (threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
subprocess.Popen(["ping.exe", "-n", "4", "127.0.0.1"], creationflags=subprocess.CREATE_NEW_CONSOLE)
logging.info("")
if __name__=='__main__':
logger = logging.getLogger('root')
FORMAT = "[TID:%(thread)d %(funcName)s L#%(lineno)s] %(message)s"
logging.basicConfig(format=FORMAT, level=logging.DEBUG)
t1 = T1()
t2 = T2()
t1.start()
t2.start()
t1.join()
t2.join()
sys.exit(0)
对于 T1 线程中的 logging.info("HEREEEEEEEE")
行,我认为应该在打印 dir 的内容后立即打印它。
对我来说没有意义的是:为什么该行没有立即打印,而是在线程 T2 完成后 4 秒后打印?
不知道是否与多线程中的文件描述符有关。
最佳答案
对于 Python 2,您的代码存在竞争条件,可能会泄漏 T1
创建的管道的可继承写入端。线程进入由 T2
创建的 ping.exe 进程线。 readline
在管道关闭之前,管道上的 不会返回,这需要关闭写入端的所有句柄。
在这种情况下,您可以通过传递close_fds=True
来避免竞争条件。至Popen
创建 ping.exe 进程时。这可以防止它继承可继承的句柄,包括 T1
中重叠调用的管道句柄。线程。
一般来说,Python 3.7之前,如果需要支持并发Popen
使用覆盖的标准句柄进行调用,那么您需要包装 Popen
使用通过预先获取锁来同步调用的函数。不幸的是,这使得 Popen
调用多线程进程中的瓶颈,但没有简单的替代方案。
背景
在 Unix 中,close_fds
Popen
的参数适用于 fork
之后的子进程。如果为 true,则在调用 exec
之前将关闭所有非标准文件描述符。 ,即使没有FD_CLOEXEC
标志设置。但是,它不会关闭标准文件描述符——stdin (0)、stdout (1) 和 stderr (2)。
在 Windows 中,句柄可以标记为可继承(即 HANDLE_FLAG_INHERIT
)。默认情况下,句柄是不可继承的。如果CreateProcess
被调用 bInheritHandles
如果为 true,则所有可继承的句柄都由子级继承。 Popen
将其传递为 not close_fds
,即不关闭文件描述符意味着继承句柄[*]。
在 Windows 中,stdin
, stdout
,和stderr
Popen
的参数用于在 STARTUPINFO
中显式设置子级的标准句柄(即 hStdInput
、 hStdOutput
、 hStdError
)。如果未显式覆盖标准句柄,则父级的标准句柄将由控制台应用程序(例如 python.exe)隐式继承,但 GUI 应用程序(例如 pythonw.exe)不会隐式继承。如果显式设置,则句柄必须可继承,并且 bInheritHandles
(即 not close_fds
)必须为真。当另一个线程重叠调用 CreateProcess
时,这就是竞争条件的根源。它还继承了句柄。
在 Python 3 中,通过默认 close_fds
降低了这种竞争条件的频率。当标准句柄未被覆盖时为 true。在 3.7 中,通过在 lpAttributeList
中传递标准句柄进一步缓解了这一问题。 STARTUPINFOEX
领域。通过此更改,并发调用 Popen
可以覆盖标准句柄而不泄漏句柄。但是,句柄仍然必须是可继承的,因此仍然存在对继承句柄的其他函数的并发调用的竞争条件,例如 os.system
和os.spawnl
.
[*] 请注意,尽管有参数名称,C“文件描述符”实际上并未在 Windows 中继承。而 C 运行时可以继承 system
的文件描述符。和 spawn
/exec
函数,其使用STARTUPINFO
实现这一点没有记录。因此Popen
只继承句柄。继承非标准句柄时,您需要将句柄值传递给子级(例如通过 stdin、命令行或环境变量),您可以通过 msvcrt.get_osfhandle
获取该句柄值。 。子进程可以通过msvcrt.open_osfhandle
为继承的句柄打开一个新的文件描述符。 .
关于python - "subprocess.Popen().readline()"在多线程python中无法返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51190271/
这个问题在这里已经有了答案: What could be the reason that `require` doesn't work in some places? (3 个回答) 6 个月前关闭。
我正在使用读取行从维基百科获取一些文本。但读取行仅返回列表,而不是我想要的文本。有什么方法可以使用替代方案或解决我的问题吗? public class mediawiki { public s
我正在编写一小段代码,其中涉及使用子进程运行一个脚本来监听一些实时数据 这是我的代码: def subscriber(): try: sub = subprocess.Pope
我已包括: #include "stdio.h" #include #include 我的编译器包含标志 -lreadline 但我仍然收到错误消息: fatal error: 'readl
使用 Term::Readline::readline 停止无限循环的正确方法是什么? ? 这样我一个都看不懂 0 #!/usr/bin/env perl use warnings; use stri
标题比我的实际目标更具体: 我有一个使用 GNU Readline 的命令行程序,主要用于命令历史记录(即使用向上箭头检索以前的命令)和其他一些细节。现在,程序的输出似乎散布在用户的输入中,有时是可以
在 ipython 中,如果我按“esc”,然后按“enter”(可能还有其他字符?),读行会中断。我无法再使用“向上”键搜索命令历史记录,并且某些命令(例如 control-K)失败。 有没有办法在
我在使用 readlines() 和 readline() 返回值时遇到问题,但在使用 read() 时却没有。任何人都知道这是怎么发生的?欣赏一下 with open('seatninger.txt
标题比我的实际目标更具体: 我有一个使用 GNU Readline 的命令行程序,主要用于命令历史记录(即使用向上箭头检索以前的命令)和其他一些细节。现在,程序的输出似乎散布在用户的输入中,有时是可以
我正在编写一个聊天客户端,它必须在接收用户输入的同时输出接收到的消息。 到目前为止,我已经 fork 成两个独立的进程,其中一个继续监听套接字连接并用 printf 写出接收到的字符串。另一个使用 r
我在 NetworkStream 上使用 StreamReader,我只想读取一行或多行,而另一个数据是 byte array(如文件数据)我不想在 StreamReader 中读取该文件数据,例如我
我遇到了这两个 API,用于在 C# 的简单控制台应用程序中读取用户的输入: System.Console.ReadLine() System.Console.In.ReadLine() 这是一个我试
yum 我的系统显示已安装 readline rlwrap-0.41]$ sudo yum install readline Loaded plugins: fastestmirror, presto
我尝试做 this tutorial在 Rust 中,到目前为止,我在将 C 库连接到 Rust 时遇到了很多问题。 C 等效代码: #include #include #include #in
我正在寻找 web Python的标题中提到的命令及其区别;但是,我并不满足于对这些命令有完整的基本理解。 假设我的文件只有以下内容。 This is the first time I am posi
你如何在 F# 中使用 Console.Readline?与 Console.Writeline 不同,当我调用它时,它并没有受到尊重。 最佳答案 如果你使用 let s = Console.Read
在一次面试中,面试官问我为什么 readline() 比 Python 中的 readlines() 慢很多? 我回答的是readlines()需要多次读取,需要更多的开销。 不知道我的回答对不对。
要在 OSX Lion 上完全运行 ipython 需要什么?我试图让 ipython 与 readline 一起工作,但没有成功。 我的做法: (在虚拟环境中) pip install ipytho
在 Nodejs 文档中,我看到: import EventEmitter from 'events'; import { readFile } from 'fs'; import fs, { rea
我写了一个简单的应用程序: #include #include #include #include int main() { char *user_input; while(u
我是一名优秀的程序员,十分优秀!