3

私はこれに数時間取り組んできましたが、良い解決策を思いつくことができませんでした. ちょっとした背景として、コマンド ラインからクローズド ソースのパスワード クラッキング プログラムを実行していますが、GPU の温度が高くなりすぎると常に一時停止する必要があります。

私はこのプログラムを使って python で他の操作を行っているので、それが私が好む言語です。とにかく、パスワード プログラムは、それがどの程度うまく機能しているか、GPU の温度などを定期的に更新し、いつでも一時停止できるようにします。

温度は問題ありませんが、ブロッキングの問題により、一時停止コマンドを送信できないと思います。少なくとも何もしていません。出力をスレッド化する例をいくつか見てきましたが、スレッド化された入力と出力を問題なく使用する例は見たことがありません。

つまり、現在の POPEN の制約の下ではこれが不可能である可能性があることはわかっていますが、何らかの方向性を示していただければ幸いです。

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]

これが私のコードの要点です。まだハッキーな段階なので、ベスト コーディング プラクティスに従っていない可能性があることはわかっています。

4

2 に答える 2

1

簡単なポータブル ソリューションは、ここでスレッドを使用することですブロックのバッファリングの問題がなければ十分です。

過熱が検出された場合に出力を読み取り、入力を停止するには (テストされていません):

#!/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)
于 2015-10-20T15:29:12.187 に答える