source

Python에서 백그라운드 프로세스를 시작하는 방법

lovecheck 2022. 11. 28. 21:16
반응형

Python에서 백그라운드 프로세스를 시작하는 방법

셸 스크립트를 훨씬 읽기 쉬운 python 버전으로 이식하려고 합니다.원래의 셸 스크립트는 백그라운드에서 "&"로 여러 프로세스(유틸리티, 모니터 등)를 시작합니다.어떻게 하면 비단뱀에서도 같은 효과를 얻을 수 있을까요?python 스크립트가 완료되었을 때 이러한 프로세스가 중단되지 않았으면 합니다.데몬의 컨셉과 관련이 있다고 생각합니다만, 어떻게 하면 좋을지 잘 모르겠습니다.

jkp의 솔루션은 기능하지만 새로운 작업 방법(및 매뉴얼에서 권장하는 방법)은subprocess을 하고 에는 더 합니다.단순한 명령어의 경우 이와 동등하지만 복잡한 작업을 수행할 경우 더 많은 옵션을 제공합니다.

사용 예:

import subprocess
subprocess.Popen(["rm","-r","some.file"])

하면 .rm -r some.file배경화면.콜링에 주의해 주세요..communicate()에서 Popen실행할 .

import subprocess
ls_output=subprocess.Popen(["sleep", "30"])
ls_output.communicate()  # Will block for 30 seconds

메뉴얼을 참조해 주세요.

또한 여기서 사용하는 "배경"은 완전히 셸 개념입니다.기술적으로는 프로세스가 완료될 때까지 블로킹 없이 생성되어야 한다는 것을 의미합니다.다만, 여기서 「background」라고 하는 것은, 셸 배경과 같은 동작을 가리킵니다.

주의: 이 답변은 2009년에 게시되었을 때보다 덜 최신입니다.사용방법subprocess다른 답변에 표시된 모듈은 이제 문서에서 권장됩니다.

(서브프로세스 모듈은 새로운 프로세스를 생성하고 결과를 취득하기 위한 보다 강력한 기능을 제공합니다.이러한 기능을 사용하는 것보다 해당 모듈을 사용하는 것이 좋습니다).


는 이 를 사용할 수 .system()같은 , 셸 스크립트로 됩니다.spawn

import os
os.spawnl(os.P_DETACH, 'some_long_running_command')

이 낮은 것( 휴대성이 낮은 것)을 해 볼 도 있습니다).os.P_NOWAIT

메뉴얼을 참조해 주세요.

아마도 "Python에서 외부 명령을 호출하는 방법"에 대한 답변을 원할 것입니다.

은 '어디로 하다'를 하는 것입니다.os.system★★★★★★★★★★★★★★★★:

import os
os.system("some_command &")

으로는 어떤 으로든 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★.system스크립트에서 셸에 전달한 것과 동일하게 함수가 실행됩니다.

여기서 찾았습니다.

xp 프로세스가 Windows(win xp)가 될 .longtask.py작업이 완료되었습니다.CGI 스크립트에서 원하는 것이 아닙니다.이 문제는 PHP 커뮤니티에서 Python만의 문제가 아닙니다.

해결책은 합격하는 것이다.DETACHED_PROCESS 기반 프로세스 생성 플래그CreateProcesswin API에서 기능합니다.pywin32가 설치되어 있는 경우 win32 process 모듈에서 플래그를 Import할 수 있습니다.그렇지 않은 경우에는 사용자가 직접 플래그를 정의해야 합니다.

DETACHED_PROCESS = 0x00000008

pid = subprocess.Popen([sys.executable, "longtask.py"],
                       creationflags=DETACHED_PROCESS).pid

사용하다subprocess.Popen()와 함께close_fds=True생성된 하위 프로세스를 Python 프로세스 자체에서 분리하여 Python이 종료된 후에도 계속 실행할 수 있도록 합니다.

https://gist.github.com/yinjimmy/d6ad0742d03d54518e9f

import os, time, sys, subprocess

if len(sys.argv) == 2:
    time.sleep(5)
    print 'track end'
    if sys.platform == 'darwin':
        subprocess.Popen(['say', 'hello'])
else:
    print 'main begin'
    subprocess.Popen(['python', os.path.realpath(__file__), '0'], close_fds=True)
    print 'main end'

출력 캡처 및 백그라운드 실행 모두threading

답변에서 설명한 바와 같이, 다음과 같이 출력을 캡처할 경우stdout=그리고 나서read()프로세스가 차단됩니다.

다만, 이것이 필요한 경우가 있습니다.예를 들어, 두 프로세스 간의 포트를 통해 통신하고 stdout을 로그 파일과 stdout에 저장하는 두 가지 프로세스를 실행하려고 합니다.

모듈에서는 그렇게 할 수 있습니다.

먼저 이 질문에서 출력 리다이렉션 부분만 수행하는 방법을 살펴보겠습니다.Python Popen: stdout AND 로그 파일에 동시에 쓰기

그 후, 다음과 같이 입력합니다.

main.py

#!/usr/bin/env python3

import os
import subprocess
import sys
import threading

def output_reader(proc, file):
    while True:
        byte = proc.stdout.read(1)
        if byte:
            sys.stdout.buffer.write(byte)
            sys.stdout.flush()
            file.buffer.write(byte)
        else:
            break

with subprocess.Popen(['./sleep.py', '0'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) as proc1, \
     subprocess.Popen(['./sleep.py', '10'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) as proc2, \
     open('log1.log', 'w') as file1, \
     open('log2.log', 'w') as file2:
    t1 = threading.Thread(target=output_reader, args=(proc1, file1))
    t2 = threading.Thread(target=output_reader, args=(proc2, file2))
    t1.start()
    t2.start()
    t1.join()
    t2.join()

sleep.py

#!/usr/bin/env python3

import sys
import time

for i in range(4):
    print(i + int(sys.argv[1]))
    sys.stdout.flush()
    time.sleep(0.5)

실행 후:

./main.py

stdout은 0.5초마다 갱신되며, 2행마다 갱신됩니다.

0
10
1
11
2
12
3
13

각 로그 파일에는 특정 프로세스에 대한 각 로그가 포함되어 있습니다.

출처 : https://eli.thegreenplace.net/2017/interacting-with-a-long-running-child-process-in-python/

Ubuntu 18.04, Python 3.6.7에서 테스트 완료.

OS 모듈에서 (인터랙티브세션을 열어 도움말을 발행함으로써) 다양한 스레드 포킹에 대해 조사를 시작할 수 있습니다.관련 기능은 fork 및 exec 기능입니다.시작 방법에 대한 아이디어를 제공하려면 포크를 실행하는 함수에 다음과 같은 내용을 넣으십시오(이 함수는 프로그램 이름과 매개 변수를 포함하는 인수로 목록 또는 태플 'args'를 사용해야 합니다. 또한 새 스레드에 대해 stdin, out 및 err를 정의할 수도 있습니다).

try:
    pid = os.fork()
except OSError, e:
    ## some debug output
    sys.exit(1)
if pid == 0:
    ## eventually use os.putenv(..) to set environment variables
    ## os.execv strips of args[0] for the arguments
    os.execv(args[0], args)

사용할 수 있습니다.

import os
pid = os.fork()
if pid == 0:
    Continue to other code ...

그러면 python 프로세스가 백그라운드에서 실행됩니다.

아직 시도하지 않았지만 .py 파일 대신 .pyw 파일을 사용하면 도움이 될 것입니다.pyw 파일에는 콘솔이 없기 때문에 이론적으로는 백그라운드 프로세스와 같이 표시되지 않습니다.

언급URL : https://stackoverflow.com/questions/1196074/how-to-start-a-background-process-in-python

반응형