2011-09-21 2 views
3

Windows에서 그렇습니다.파이썬 CGI 스크립트에서 백그라운드 작업을 끝내기 위해 기다리지 않고 간단히 시작할 수 있습니까?

이 질문에 대한 대답은 Windows 서비스를 만들어야한다는 것입니다. 이것은 내가하려고하는 것에 대해 우스꽝스럽게 헤비급 것처럼 보인다.

저는 관리자를 위해 약간의 프로토 타입을 함께 사용하려고합니다. 제품화에 대한 책임을지지 않을 것입니다. 사실, 제품화 될 수 없습니다. 그것은 단지 약간의 연구자들이 함께 놀 수있는 무언가 일 수 있습니다.

업로드 할 파일을 받고 임시 위치에 저장 한 다음 백그라운드 프로세스를 실행하여 파일에 심각한 문제를 발생시키는 CGI 스크립트가 있습니다. 그런 다음 Javascript 도구를 사용하여 다른 CGI 스크립트를 호출하여 상태를 확인하고 필요에 따라 페이지를 업데이트합니다.

이 모든 것은 작동하지만, 저주받은 웹 서버는 서브 프로세스가 실행되는 동안 연결을 닫지 않습니다. 몇 가지 조사를 해봤는데, 유닉스에 대한 답은 데몬이 될 것입니다.하지만 지금은 Windows에 붙어 있습니다. Windows 서비스로 만들려는 답변이 있습니까? 이것은 믿을 수 없을 정도로 무거워 보이며, 프로세스를 시작한 다음 서버 연결을 닫습니다.

정말 유일한 방법입니까?

편집 : 좋아, 이상 여기에 멋진 작은 해킹을 발견 (선택 (3) 사람은 준다) : How to completely background a process in Perl CGI under IIS

이것은을하지만 난 그게 더 간단하게이 문제를 수정할 수 있었고, klugey 솔루션을 사용하면 빠르고 간단한 프로토 타입을 만들 때 적합합니다.

subprocess.Popen("python.exe","myscript.py","arg1","arg2") 

작동하지 않는, 내가 설명한대로 :

그래서 나는 처음에 내 주요 스크립트가이 일을했다.

$("#somecrap").load("launchBackgroundProcess.py", {arg1:"foo",arg2:"bar"}); 

을 그리고 launchBackgroundProcess.py는 subprocess.Popen는 않는 대신, 나는 지금 내 주요 스크립트는 문서가 완전히로드 된 후 실행되는 자바 스크립트의 약간을 방출합니다.

이 솔루션은 백그라운드 작업이 실행되는 동안 브라우저 연결을 열어두기 때문에 절대로 확장되지 않습니다. 하지만이 작은 thinger 이후로 나는 일 수도 있고 언젠가는 (심지어는 의심 스럽지만) 언젠가는 2 명의 동시 사용자가 리소스를 걱정하지 않을 수도 있습니다. 이는 사용자가 정당한 이유없이 http 연결이 열려있는 경우에도 메인 페이지를보고 자바 스크립트 업데이트를 얻을 수있게합니다.

답변 해 주셔서 감사합니다. 이 제품을 생산하도록 요청하는 경우 Profane이 권장하는 자료를 참조하겠습니다.

+0

작동하는지는 확실치 않지만 백그라운드 프로세스를 시작하기 위해 별도의 스레드를 생성하려고 했습니까? 주 기능은 다시 스레드에 다시 참여하기를 기다리지 않고 돌아올 수 있습니다 ... –

+0

그건 같은 문제가 있습니다. 분명히하기 위해서 : 파이썬 스크립트 자체는 프로세스가 돌아 오기를 기다리지 않고 내 스크립트는 아무 문제없이 끝납니다. 그러나 Apache는 하위 프로세스가 종료 될 때까지 http 연결을 열어 둡니다. – user435779

답변

1

Windows 프로그래밍에 익숙하지 않고 MSDN 문서를 잘 보지 않으려면 나는 Mark Hammond의 cannonical guide 사본을 받기를 원할 수 있습니다. 모든 것 파이썬과 창문. 이런 종류의 반복적 인 질문들 중 많은 것들에 대해 어떻게 든 구식이되지는 않습니다. 모든 플랫폼 솔루션으로 프로세스를 시작하는 대신 win32process 모듈을 사용하는 것이 더 나을 것입니다. Hammond 책의 17 장은 이것을 광범위하게 다루지 만, pywin ide (필자가 pypi에서 다운로드 할 수있는 windows extensions에 번들로 포함되어있다)를 다운로드하고 도움말 문서를 살펴 보는 것만으로도 충분할 것이다. 파이썬의 윈도우 API. 다음은 최근에 작업하고있는 프로젝트의 api 사용 예입니다. 사실 약간의 적응으로 당신이 원하는 것을 할 수 있습니다. CreationFlags에 집중하고 싶을 것입니다. 특히 win32process.DETACHED_PROCESS는 "백그라운드에서 콘솔 프로그램을 실행하는 데 자주 사용됩니다." 많은 다른 플래그가 사용 가능하지만 편리하게 감 쌉니다.

if subprocess.mswindows: 
     su=subprocess.STARTUPINFO() 
     su.dwFlags |= subprocess._subprocess.STARTF_USESHOWWINDOW 
    process = subprocess.Popen(['program', 'flag', 'flag2'], bufsize=-1, 
       stdout=subprocess.PIPE, startupinfo=su) 
1

간단한, 그러나 가장 효율적인 방법은 또 다른 파이썬 실행

from subprocess import Popen 
Popen("python somescript.py") 
+0

아니요, 작동하지 않습니다. 그것이 내가 이미하고있는 것입니다. Windows가 프로세스를 관리하는 방식으로 인해이 간접적 인 방식으로 자식 프로세스를 시작하면 자식 프로세스가 종료 될 때까지 부모 프로세스가 사라지지 않습니다. 그래서 웹 서버는 연결을 열어두고 그냥 거기에 있습니다. – user435779

+0

+1은 이미 이것이 당신의 접근 이었다는 것을 깨닫지 못했습니다; 프로세스 자체를 다시 작성하는 것보다는이 방법을 적용하는 것이 더 쉬운 방법 일 것입니다. DETACHED_PROCESS 플래그로 시작하십시오. – Profane

1

당신은 단지 "시작"창 명령을 사용하여 system 전화를 사용할 수 있습니다를 실행하는 것입니다. 이 방법은 파이썬 스크립트가 시작된 프로그램의 완료를 기다리지 않습니다.

+0

시작이이 방법으로 작동했는지 알 수 없습니다. (Win32 프로세스에서) 커스터마이징이 필요하지 않고 Popen 기능이 필요없는 경우 스크립트와 독립적 인 새로운 프로세스를 만드는 가장 빠른 방법일까요? – Profane

+0

동일한 문제가있는 것으로 보입니다. 내가 인터넷 검색에서 겪었던 문제 -이 답변으로 같은 문제가 나타납니다. - 사람들이이 문제가 CGI *에 고유하다는 것을 이해하지 못하는 것 같습니다. CGI가 아닌 컨텍스트에서 다른 프로세스를 생성하는 메서드는 웹 서버에서 연결을 계속 유지합니다. – user435779

+0

@ user435779 : CGI로 작업 할 때 이런 종류의 문제는 없었지만 IIS는 사용하지 않았지만 파이썬 웹 서버는 사용하지 않았습니다. CGI 프로토콜에는 기다릴 요청은 없지만 IIS가 무엇을하고 싶어하는지 실제로 알 수는 없습니다. 실제로'system ("start xxx")'이 다른 프로세스를 시작한다는 것은 이해하기 어렵습니다 (afaik는 시스템 훅을 설치해야합니다). – 6502

0

CGI 스크립트는 TCP 소켓이나 파이프로 직접 리다이렉트 된 표준 출력으로 실행됩니다. 일반적으로 연결은 핸들과 핸들의 모든 복사본이 닫힐 때까지 닫히지 않습니다. 기본적으로 하위 프로세스는 핸들 사본을 상속합니다.

하위 프로세스에서 연결이 대기하는 것을 방지하는 두 가지 방법이 있습니다. 하나는 서브 프로세스가 핸들을 상속하지 못하도록하는 것이고, 다른 하나는 서브 프로세스가 시작될 때 핸들 사본을 닫는 것입니다. 당신이 핸들을 상속 서브 프로세스를 방지하려면 당신이있는 경우

close(STDOUT); 

, 당신은합니다 (SetHandleInformation 기능을 사용할 수 있습니다 : 하위 프로세스가 펄에있는 경우

, 나는 당신이 매우 간단하게 핸들을 닫을 수 있다고 생각 Win32 API에 대한 액세스) 또는 CreateProcess 호출에서 bInheritHandles를 FALSE로 설정하십시오. 또는 하위 프로세스를 시작하기 전에 핸들을 닫습니다.

+0

STDOUT을 닫는 것은 내가 시도한 이전 일 중 하나였습니다 - nada. Profane의 DETACHED_PROCESS 사용에 대한 제안은 효과가 있었을 것이라고 생각합니다. 그러나 지금까지 해킹 해낸 해킹이 지금까지 작업을 완료 했으므로 더 이상 파고 들지 못했습니다. 프로토 타입은 현재 순환 파일에있는 것으로 보입니다. – user435779

+0

STDOUT과 STDERR을 동시에 닫으려고 했습니까? 나는 DETACHED_PROCESS가 어떤 영향을 주었다면 매우 놀랍습니다. Python CGI 스크립트를 실행할 때 웹 서버가 콘솔을 만들지 않을 이유가 없기 때문에, 그 존재를 감시하는 것을 신경 쓰지 않기 때문입니다. 그러나 그것은 웹 서버에 의존하므로 YMMV. –

관련 문제