首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用subprocess.POPEN获取异步输入和输出

如何使用subprocess.POPEN获取异步输入和输出
EN

Stack Overflow用户
提问于 2015-10-20 17:07:05
回答 2查看 2.3K关注 0票数 3

我已经为此工作了几个小时,还没有想出一个好的解决方案。有一点背景,我正在运行一个密码破解程序,它是从命令行关闭的源代码,但当我的gpu温度变得太热时,必须不断地暂停它。

我在python中使用这个程序做其他操作,所以这是我更喜欢的语言。无论如何,密码程序会定期更新它的运行情况,gpu温度等,并允许我随时暂停它。

我的温度正常,但由于阻塞问题,我猜我不能发送暂停命令。至少它什么也做不了。我见过几个线程化输出的例子,但还没有看到使用线程化输入和输出而不会导致任何问题的东西。

我的意思是,据我所知,在目前的POPEN限制下,这可能是不可能的,但希望能有一些指导。

代码语言:javascript
复制
popen = Popen(command, stdout=PIPE, stdin=PIPE, shell=True)
lines_iterator = iter(popen.stdout.readline, b"")
while 1:
    for line in lines_iterator:
        cleanLine = line.replace("\n", "")
        p = re.compile('[0-9][0-9]c Temp')
        m = p.search(cleanLine)
        print cleanLine
        if m:
            temperature = m.group(0)
            if int(temperature[:2]) > 80:
                overheating = True
                print "overheating"
        if overheating:
            if "[s]tatus [p]ause [r]esume [b]ypass [q]uit" in line:

                #It's not doing anything right here, it just continues
                print popen.communicate("p")[0]

这是我代码的要点。它还在某种程度上处于开发阶段,所以我知道它可能没有遵循最佳的编码实践。

EN

回答 2

Stack Overflow用户

发布于 2015-10-20 17:32:51

编辑:对不起,我在最初的回答中对overheating的范围感到困惑。我删除了我答案的第一部分,因为它已经不再相关了。

communicate将等待进程退出,因此它可能不是您在本例中要查找的内容。如果你想让这个过程继续下去,你可以使用像popen.stdin.write("p")这样的东西。如果您的进程需要,您可能还需要发送一个"\n“。

此外,如果您对额外的依赖项没问题,那么您可能会对设计用于控制交互式进程的pexpect模块感兴趣。

票数 1
EN

Stack Overflow用户

发布于 2015-10-20 23:29:12

一个简单的可移植的解决方案是use threads here。如果没有block buffering issues就足够了。

如果检测到过热(未测试),则读取输出并停止输入:

代码语言:javascript
复制
#!/usr/bin/env python
from subprocess import Popen, PIPE, CalledProcessError
from threading import Event, Thread

def detect_overheating(pipe, overheating):
    with pipe: # read output here
        for line in iter(pipe.readline, ''): 
            if detected_overheating(line.rstrip('\n')):
                overheating.set()    # overheating
            elif paused: #XXX global
                overheating.clear()  # no longer overheating

process = Popen(args, stdout=PIPE, stdin=PIPE, bufsize=1,
                universal_newlines=True) # enable text mode
overheating = Event() 
t = Thread(target=detect_overheating, args=[process.stdout, overheating])
t.daemon = True # close pipe if the process dies
t.start()
paused = False
with process.stdin: # write input here
    while process.poll() is None:
        if overheating.wait(1): # Python 2.7+
            # overheating
            if not paused:
                process.stdin.write('p\n') # pause
                process.stdin.flush()
                paused = True
        elif paused: # no longer overheating
            pass #XXX unpause here
            paused = False
if process.wait() != 0: # non-zero exit status may indicate failure
    raise CalledProcessError(process.returncode, args)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33232447

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档