2011-02-12 2 views
5

질문 :gevent와 다중 처리를 함께 사용하여 서브 프로세스와 통신

Windows에서 gevent와 함께 다중 처리 모듈을 효율적으로 사용할 수 있습니까?

시나리오 :

내가 Windows에서 비동기 I/O를하고 gevent 기반의 파이썬 응용 프로그램이 있습니다. 응용 프로그램은 대부분 I/O 바운드이지만 CPU로드가 증가 할 수도 있습니다. 이 응용 프로그램은 stdin 및 stdout을 통해 콘솔 응용 프로그램을 제어해야합니다. 이 콘솔 응용 프로그램을 수정할 수 없으며 사용자가 자신의 사용자 지정 응용 프로그램을 사용할 수있게되며 텍스트 (회선) 기반 통신 프로토콜 만 수정됩니다.

하위 프로세스와 스레드를 사용하여 작동하는 구현이 있지만, 하위 프로세스 기반 통신 코드를 해당 스레드와 함께 별도 프로세스로 이동하여 주 응용 프로그램을 다시 단일 스레드로 되돌릴 수 있습니다. 나는 이것을 위해 멀티 프로세싱 모듈을 사용할 계획이다.

전에 읽기 :

나는 웹에게 많은 검색 및 일부 소스 코드를 읽고, 그래서 멀티 프로세싱 모듈은 Windows에서 명명 된 파이프를 기반으로 파이프 구현을 사용하고 있음을 알 수있다. 한 쌍의 multiprocessing.queue.Queue 객체는 두 번째 파이썬 프로세스와 통신하는 데 사용됩니다. 이러한 대기열은 해당 Pipe 구현을 기반으로합니다. IPC는 명명 된 파이프를 통해 수행됩니다.

중요한 질문은 들어오는 Queue의 get 메소드를 호출하면 gevent의 주 루프를 차단하는지 여부입니다. 그 방법에 대한 타임 아웃이 있기 때문에 작은 타임 아웃으로 루프를 만들 수 있지만, 좋은 I/O 대기 시간을 저해하는 작은 시간 동안은 여전히 ​​막을 수 있기 때문에 좋은 해결책은 아닙니다.

나는 또한 열심히 그리고 때때로 깨지기 쉬운 것으로 알려진 Windows에서 파이프를 사용하는 모든 문제를 우회하는 방법에 대한 제안에 대해 열려 있습니다. 공유 메모리 기반 IPC가 Windows에서 가능한지 아닌지 확실하지 않습니다. 어쩌면 콘솔 응용 프로그램을 네트워크 소켓을 사용하는 자식 프로세스와 통신 할 수있는 방법으로 포장 할 수 있습니다.이 소켓은 gevent와 잘 작동하는 것으로 알려져 있습니다.

가능하면 주 사용 사례에 질문하지 마십시오. 감사.

+0

Windows와 UNIX 모두에서 하위 프로세스의 파이프를 비동기 적으로 읽고 쓸 수있는 모듈을 발견했습니다. gevent의 이벤트 루프와 통합하여 상당히 일반적인 솔루션을 얻을 수 있습니다. http://code.activestate.com/recipes/440554-module-to-allow-asynchronous-subprocess-use-on-win/ – fviktor

답변

1

대기열 가져 오기 방법이 실제로 차단됩니다. 타임 아웃과 함께 사용하면 잠재적으로 문제를 해결할 수 있지만 확실히 가장 깨끗한 솔루션은 아니며 가장 중요한 것은 정당한 이유없이 여분의 대기 시간을 도입합니다. 그것이 막히고 있지 않더라도, 그것은 좋은 해결책이 될 수 없습니다. 비 블로킹 자체만으로는 충분하지 않기 때문에 좋은 비동기 호출/API는 사용중인 I/O 프레임 워크에 원활하게 통합되어야합니다. 파이썬에서는 gevent, C에서는 libevent, C++에서는 Boost ASIO가되어야합니다.

가장 쉬운 해결책은 콘솔 응용 프로그램을 생성하고 콘솔의 내부 및 외부 디스크립터에 연결하여 간단한 I/O를 사용하는 것입니다. 고려해야 할 두 가지 중요한 요소가 있습니다.

  • 클라이언트가 클라이언트 응용 프로그램을 작성하는 것은 매우 쉽습니다. 그들은 어떤 종류의 IPC, 소켓 또는 다른 코드로도 작업하지 않아도되며, 이는 많은 사람들에게 매우 어려운 일이 될 수 있습니다. 이 방법을 사용하면 응용 프로그램은 stdin을 읽고 stdout에 쓸 것입니다.
  • 수동으로 시작할 수 있고 콘솔에 텍스트를 입력하고 결과를 볼 수 있으므로이 방법을 사용하여 콘솔 응용 프로그램을 테스트하는 것은 매우 쉽습니다.
  • Gevent는 비동기 읽기/쓰기에 가장 적합합니다.

그러나이 응용 프로그램을 시작해야하며 동시 통신이 지원되지 않으며 네트워크를 통한 통신이 지원되지 않는다는 단점이 있습니다. good example for starters도 있습니다.

간단하면서도 유연하게 유지하려면 TCP/IP 소켓을 사용할 수 있습니다. 클라이언트와 서버가 동일한 시스템에서 실행중인 경우 또한 우수한 운영 체제는 IPC를 기본 구현으로 사용하므로 속도가 빠릅니다. 그리고이 경우의 성능에 대해 걱정한다면 Python을 전혀 사용하지 말고 다른 기술을 살펴보아야합니다.

짝수 솔루션 - 사용 ZeroC ICE. 거의 모든 프로세스 간 통신을 가능하게하는 매우 현대적인 기술입니다. 그것은 매우 사용하기 쉬운 CORBA 킬러입니다. 그것은 많은 사람들이 많이 사용하고 있으며, 동급에서 가장 빠르며 안정된 상태를 유지하고 있습니다. 이 솔루션의 장점은 Python, Java, C++ 등의 다양한 언어로 프로그램을 완벽하게 통합 할 수 있다는 것입니다.하지만 개념에 익숙해 지려면 시간이 필요합니다. 이 방법을 사용하기로 결정했다면, 저물통 문서를 읽는 데 하루를 보내십시오.

희망이 있습니다. 행운을 빕니다!

+0

감사합니다. 상세히. gevent processes.py 예제의 문제점은 단 하나의 통신 단계 만 구현한다는 것입니다. 우리는 언제든지 데이터를 전송할 수있는 작업자를 사용하고 있으며 그 동안 stop 명령과 같은 명령을 보낼 수 있습니다. 하지만 하위 프로세스를 종료하지는 못하고 계속 사용할 수 있어야합니다. 그러나 두 개의 루프를 통합하려고합니다. Windows에서는 도움이되지 않지만 시도해 볼 가치가 있습니다. TCP/IP를 사용하는 것은 내가 생각하고있는 또 다른 옵션이지만 래퍼 레이어가 필요하다. 이는 래퍼 레이어를 필요로 할 것이다. ZeroC ICE를 살펴 보겠습니다. – fviktor

+0

@fviktor : 천만에. 비동기 I/O를 사용하여 언제든지 데이터를 전송할 수 있습니다. 당신이 보증해야 할 유일한 것은 당신이 병렬로 다중 쓰기를 수행하지 않을 것이라는 것입니다. 이 경우 전용 작성기 스레드 및 일부 큐가 도움이됩니다. –

0

귀하의 질문은 이미 상당히 오래된 것입니다. 그럼에도 불구하고 나는 매우 똑 바른 방식으로 윤곽이 그려진 도전에 대처할 것이라고 - 나는 믿는다 - http://gehrcke.de/gipc을 추천하고 싶다. 기본적으로 멀티 프로세싱 기반의 자식 프로세스를 응용 프로그램의 모든 위치 (Windows에서도)에 통합 할 수 있습니다. Process 개체 (예 : join())와의 상호 작용은 협동 적입니다. 파이프 관리를 통해 프로세스 간 통신을 협업 적으로 차단할 수 있습니다. 그러나 Windows에서는 IPC가 POSIX 호환 시스템보다 훨씬 효율적입니다 (비 차단 I/O는 스레드 풀을 통해 모방되므로). 응용 프로그램의 IPC 메시징 볼륨에 따라 중요하거나 중요하지 않을 수 있습니다.

관련 문제