2016-12-22 12 views
0

C++에서 popen() 함수로 프로세스 (GNUplot)를 열었습니다. Ctrl + C를 눌러 프로세스를 종료하면 GNUplot은 또한 SIGINT 신호를받습니다. 나는 이것이 내가하는 일에 불리한 영향을 미치기 때문에 일어나는 것을 막고 싶다. (나는 자신의 시그널 핸들러 함수로 시그널을 처리하는 것을 선호한다). 어떻게해야합니까?C++에서 popen()으로 열린 프로세스가 SIGINT 신호를받지 못하도록하려면 어떻게해야합니까?

나는 plot '-' 명령을 사용하여 플롯하고 플롯 할 모든 값을 반복합니다. gnuplot이 중간에 SIGINT를 받으면 전체 플롯을 완료하지 않고 중간에 플로팅을 멈출 수 있습니다. 전체 음모를 완성하고 싶습니다. 이것은 내가 가진 바람직하지 못한 영향이다.

+0

피해야 할 부작용이 무엇인지 설명하십시오. –

+0

나는 당신이 피하고자하는 "불리한 효과"가 무엇인지를 설명하기 위해 편집하지 않았기 때문에 마침내 질문에 답하지 않았다. –

+0

@BasileStarynkevitch 질문을 편집했습니다. –

답변

0

popen(3) 명령 문자열에 새 쉘 /bin/sh -c이 실행 중입니다.

셸의 trap builtin은 신호를 처리합니다. 비어있는 첫 번째 인수로 무시합니다. 그래서 당신은

FILE* f = popen("trap '' TERM INT; gnuplot", "w"); 

이 BTW, POSIX trapSIG 접두사없이 익명을 신호를 필요로 할 수 있습니다.

하지만 그 gnuplot 이후 자체가 명시 적으로handling signals이다, 작동하지 않습니다. gnuplot 외부를 피할 방법이 없습니다. 그러나 free software 성격의 gnuplot을 활용하십시오 : 소스 코드를 다운로드하여 연구하고 기묘한 요구에 맞게 패치하십시오. FWIW, SIGINTsignal은 소스 코드 gnuplot-5.0.5의 여러 위치에 나타납니다.

그러나, 당신은 (fork, execve, pipe, dup2, waitpid, signal ...) 낮은 수준의 시스템이 명시 적으로 호출 전화 (대신 popen를 사용하는)을 고려해야합니다. 자세한 내용은 Advanced Linux Programming을 참조하십시오.


이 난 강력하게 귀하의 질문은 XY problem이라고 생각한다. 당신은 실제로 피하려고하는 "불리한 영향"에 대해 설명하지 않으며, 그렇지 않으면 피할 수 있다고 생각합니다.

나는 plot '-' 명령을 사용하여 플롯하고 플롯하려는 모든 값을 반복합니다. gnuplot이 중간에 SIGINT를 받으면 전체 플롯을 완료하지 않고 중간에 플로팅을 멈출 수 있습니다. 전체 음모를 완성하고 싶습니다.

사실 당신은 gnuplot 위해 (gnuplot 측면에서 볼 때 입력 하나, 출력 하나, 표준 에러 아마도 하나) 두 개 또는 세 개의 파이프를 설정할 수 있습니다. 낮은 수준의 시스템 호출 (명시적인 호출 pipe(2), fork(2) 등 ...) 호출해야합니다. 그러면 프로그램에 event loop (아마도 poll(2) ...을 기반으로 함)이 있어야합니다. 그리고 plot '-' 이후에 command을 gnuplot에 보내야합니다. set print '-'으로 초기화하거나 stderrgnuplot 인 다른 파이프를 사용해야합니다. 그러면 이벤트 루프가 DONE 메시지를 동기화하여 동기화합니다. this도 읽으십시오.

+0

제 제안은'popen'을 피하고 하위 레벨 시스템 호출을 사용하는 것입니다. –

+0

오타를 만들었는데'SIGTERM'이 아닌'trap ''TERM'입니다. 그러나 나는 당신의 경우에'popen'을 피하는 것이 좋습니다. –

+0

코드가 작동합니다! –

0

나는 당신과 비슷한 문제가있었습니다.-batch 매개 변수와 함께 tc 명령을 사용하고 있으며 한계에 도달 한 후 종료되고 닫힐 때까지 살아 있어야합니다. 내 문제는 두 개의 비동기 popen 프로세스를 실행하고 예외를 throw 한 후 두 번째 프로세스가 종료되었다는 것입니다. 많은 메모리 덤프 등.이 문제를 발견하고 수정 한 후, 이제는 SIGINT, SIGTERM, ctrl + c를 처리 할 수 ​​있습니다. 트랩이나 비슷한 것은 필요 없습니다.