문제

나는 상대적으로 쉽게 생각할 것이라고 생각했지만 내가 기대했던 고통으로 밝혀졌습니다. 첫째, 상호 작용하는 대부분의 코드는 제어 할 수없는 레거시 코드이므로 큰 패러다임 변경을 수행 할 수 없습니다.

다음은 내가해야 할 일에 대한 단순화 된 설명입니다. Stdin에서 읽고 Stdout에 쓴 많은 간단한 프로그램이 있다고 말합니다. (이것들은 만질 수 없습니다). 기본적으로 Stdin에 대한 입력은 "온도 설정 100"또는 그와 같은 명령입니다. 그리고 출력은 "온도가 100으로 설정되었습니다"또는 "온도가 설정 점 아래로 떨어졌습니다"이벤트입니다.

내가하고 싶은 것은이 간단한 프로그램을 시작하고 이벤트를보고 필요에 따라 명령을 보내는 응용 프로그램을 작성하는 것입니다. 나의 초기 계획은 Popen과 같은 것이었지만, 파이프를 읽고 쓰기 위해서는 입찰자 Popen이 필요합니다. 나는 popen2라고 부르는 무언가를 해킹하여 그것을 실행하도록 명령을 전달하고 읽기 및 쓰기 스트림으로 채워진 두 개의 파일*을 전달했습니다. 그런 다음 각 프로세스의 각 stdouts에서 읽는 간단한 루프를 작성하고 필요한 논리를 수행 한 다음 적절한 프로세스에 명령을 씁니다.

여기 유사 코드가 있습니다

FILE *p1read, *p1write;
FILE *p2read, *p2write;
FILE *p3read, *p3write;

//start each command, attach to stdin and stdout
popen2("process1",&p1read,&p1write);
popen2("process2",&p2read,&p2write);
popen2("process3",&p3read,&p3write);

while (1)
{
   //read status from each process
   char status1[1024];
   char status2[1024];
   char status3[1024];
   fread(status1,1024,p1read);
   fread(status2,1024,p2read);
   fread(status3,1024,p3read);

   char command1[1024];
   char command2[1024];
   char command3[1024];
   //do some logic here

   //write command back to each process
   fwrite(command1,p1write);
   fwrite(command2,p2write);
   fwrite(command3,p3write);
}

실제 프로그램은 스트림에서 엿볼 수있는 곳에서 더 복잡합니다. 대기 중이 아닌 경우, 그렇지 않은 경우에는 해당 프로세스가 건너 뛸 수 있습니다. 그러나이 코드는 기본 아이디어를 제공합니다.

이제 이것은 내 유닉스 박스에서 잘 작동하고 Cygwin이있는 Windows XP 상자에서도 꽤 좋습니다. 그러나 이제는 기본적으로 Win32 작업을 수행해야합니다.

어려운 부분은 내 Popen2가 Fork () 및 execl ()을 사용하여 프로세스를 시작하고 하위 프로세스의 stdin 및 stdout에 스트림을 할당한다는 것입니다. 창에서 이것을 할 수있는 깨끗한 방법이 있습니까? 기본적으로 UNIX 버전과 같은 방식으로 Windows에서 작동하는 POPEN2를 만들고 싶습니다. 이런 식으로 유일한 Windows 특정 코드는 그 기능에있을 것이며 같은 방식으로 작업하는 다른 모든 것을 벗어날 수 있습니다.

어떤 아이디어?

감사!

도움이 되었습니까?

해결책

Windows에서는 먼저 CreatePipe (파이프 (2)와 유사)를 호출 한 다음 CreateProcess를 호출합니다. 여기서의 속임수는 CreateProcess에 새로 만들어진 프로세스의 stderr, stdout, stdout을 통과 할 수있는 매개 변수가 있다는 것입니다.

stdio를 사용하면 파일 번호를 예상하는 파일 객체를 만들려면 fdopen을 수행해야합니다. Microsoft CRT에서 파일 번호는 OS 파일 핸들과 다릅니다. 따라서 CreatePipe의 다른 쪽 끝을 발신자에게 반환하려면 먼저 CRT 파일 번호를 얻으려면 _OPEN_OSFHANDLE이 필요합니다.

작업 코드를보고 싶다면 _pypopen을 확인하십시오.

http://svn.python.org/view/python/trunk/modules/posixmodule.c?view=markup

다른 팁

Popen2 () 함수를 사용하여 크로스 플랫폼 문제를 추상화하여 문제를 아주 잘 시작했다고 생각합니다. 나는 와서 '소켓'을 제안 할 것으로 기대했지만 질문을 읽은 후에는 관련이 없다고 확신합니다. 파이프 대신 소켓을 사용할 수 있습니다. Popen2 () 함수에 숨겨져 있습니다.

Windows API를 사용하여 Windows에서 필요한 기능을 구현할 수 있습니다. 내가 할 수없는 것은 당신에게 올바른 기능을 안정적으로 지적하는 것입니다. 그러나 Microsoft에는 대부분의 POSIX와 같은 API 호출을 사용할 수 있지만 이름은 '_'로 접두사가 있습니다. 효과를 달성하는 기본 API 호출도 있습니다. fork 그리고 exec.

귀하의 의견에 따르면 데이터 가용성 및 가능한 교착 상태와 관련된 문제를 알고 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top