복붙노트

[PYTHON] 영구적 인 파이썬 하위 프로세스

PYTHON

영구적 인 파이썬 하위 프로세스

파이썬에서 "영원한"서브 프로세스 호출을 만드는 방법이 있습니까? 여러 번로드하는 데 시간이 걸리는 프로그램을 호출하고 있습니다. 따라서 프로그램을 열어두고 죽이지 않고 열어 둘 수만 있다면 좋을 것입니다.

파이썬 스크립트의 만화 버전은 다음과 같습니다.

for text in textcollection:
    myprocess = subprocess.Popen(["myexecutable"],
                stdin = subprocess.PIPE, stdout = subprocess.PIPE,
                stderr = None)
    myoutputtext, err = myprocess.communicate(input=text)

각 텍스트를 개별적으로 처리해야하므로 모든 텍스트를 하나의 큰 텍스트 파일에 결합하고 한 번 처리하는 것은 옵션이 아닙니다.

이 옵션과 같은 옵션이있는 것이 바람직합니다.

myprocess = subprocess.Popen(["myexecutable"],
            stdin = subprocess.PIPE, stdout = subprocess.PIPE,
            stderr = None)    for text in textcollection:
for text in textcollection:
    myoutputtext, err = myprocess.communicate(input=text)

내가 프로세스를 열어 둘 수있는 곳, 정말로 감사하겠습니다.

해결법

  1. ==============================

    1.myprocess.stdin.write () 및 myprocess.stdout.read ()를 사용하여 하위 프로세스와 통신 할 수 있으므로 호출이 차단되지 않도록 올바르게 버퍼링을 처리하는지주의해야합니다.

    myprocess.stdin.write () 및 myprocess.stdout.read ()를 사용하여 하위 프로세스와 통신 할 수 있으므로 호출이 차단되지 않도록 올바르게 버퍼링을 처리하는지주의해야합니다.

    하위 프로세스의 출력이 잘 정의되어 있으면 라인 버퍼링과 myprocess.stdout.readline ()을 사용하여 안정적으로 통신 할 수 있어야합니다.

    다음은 그 예입니다.

    >>> p = subprocess.Popen(['cat'], bufsize=1, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    >>> p.stdin.write('hello world\n')
    >>> p.stdout.readline()
    'hello world\n'
    >>> p.stdout.readline()        # THIS CALL WILL BLOCK
    

    Unix에서이 방법을 사용하는 대신 파일 핸들을 비 차단 모드로두면 myprocess.stdout.read ()와 같은 함수를 호출하고 사용할 수있는 경우 데이터를 반환하거나 IOError를 발생시킬 수 있습니다 데이터가 아닙니다.

    >>> p = subprocess.Popen(['cat'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    >>> import fcntl, os
    >>> fcntl.fcntl(p.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
    0
    >>> p.stdout.read()         # raises an exception instead of blocking
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    IOError: [Errno 11] Resource temporarily unavailable
    

    이렇게하면 다음과 같이 할 수 있습니다.

    fcntl.fcntl(p.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
    for text in textcollection:
        myprocess.stdin.write(text + '\n')
        while True:
            myoutputtext = ''
            try:
                myoutputtext += myprocess.stdout.read()
            except IOError:
                pass
            if validate_output(myoutputtext):
                break
            time.sleep(.1)    # short sleep before attempting another read
    

    이 예제에서 validate_output ()은 지금까지받은 데이터가 모두 예상되는 출력이면 True를 반환하는 쓸 함수입니다.

  2. ==============================

    2.그것은 당신의 하위 프로세스를 죽이고있는 communicate () 호출입니다. 하위 프로세스 문서에 따르면 communicate () 메서드는 다음을 수행합니다.

    그것은 당신의 하위 프로세스를 죽이고있는 communicate () 호출입니다. 하위 프로세스 문서에 따르면 communicate () 메서드는 다음을 수행합니다.

    원하는 것은 POpen 객체의 stdin 및 stdout 속성과 직접 상호 작용하여 하위 프로세스와 직접 통신하는 것입니다. 그러나이 문서는 다음과 같이 권고합니다.

    따라서 잠재적 교착 상태에 대한 해결 방법을 직접 구현하거나 누군가가 비동기 서브 프로세스 모듈을 작성했기를 바랍니다.

    편집 : 다음은 비동기 서브 프로세스 모듈을 사용하는 방법에 대한 quick'n'dirty 예제입니다.

    import asyncsubprocess
    
    textcollection = ['to', 'be', 'or', 'not', 'to be', 'that is the', 'question']
    
    myprocess = asyncsubprocess.Popen(["cat"],
         stdin = asyncsubprocess.PIPE,
         stdout = asyncsubprocess.PIPE,
         stderr = None)
    
    for text in textcollection:
        bytes_sent, myoutput, err = myprocess.listen(text)
        print text, bytes_sent, myoutput, err
    

    이것을 실행하면 다음과 같이 인쇄됩니다.

    to 2 to 
    be 2 be 
    or 2 or 
    not 3 not 
    to be 5 to be 
    that is the 11 that is the 
    question 8 question 
    
  3. ==============================

    3.너를 찾고있는 것 같아.

    너를 찾고있는 것 같아.

    myprocess.stdin.write(text)
    

    당신은 Popens의 목록을 생성 한 다음 다른 루프의 각 요소에 대해 통신을 호출 할 수 있습니다. 이 같은

    processes=[]
    for text in textcollection:
        myprocess = subprocess.Popen(["myexecutable"],
                    stdin = subprocess.PIPE, stdout = subprocess.PIPE,
                    stderr = None)
        myprocess.stdin.write(text)
        processes.append(myprocess)
    
    for proc in processes:
        myoutput, err=proc.communicate()
        #do something with the output here
    

    이렇게하면 모든 Popens가 시작된 후까지 기다릴 필요가 없습니다.

  4. ==============================

    4.

    if os.name == 'nt':
     startupinfo = subprocess.STARTUPINFO()
     startupinfo.dwFlags |= subprocess._subprocess.STARTF_USESHOWWINDOW
     subprocess.call(os.popen(tempFileName), shell=True)
     os.remove(tempFileName)
    
  5. from https://stackoverflow.com/questions/8980050/persistent-python-subprocess by cc-by-sa and MIT license