2011-11-13 5 views
1

현재 C++ 내에서 작은 셸을 만드는 중입니다.이전 작업의 sigchld()를 기반으로 새 작업 실행

사용자는 exe1 && exe2 &과 같은 프롬프트에서 작업을 입력 할 수 있습니다. BASH 셸과 마찬가지로 이 성공적으로 종료되는 경우에만 exe2을 실행합니다. 또한 전체 작업을 배경에서 수행해야합니다 (후행 & 연산자로 지정).

지금은 jobManager으로 작업 실행을 처리하고 job 구조에는 작업 실행 파일과 개별 인수/조건이 들어 있습니다. 작업은 fork()을 호출 한 다음 적절한 인수를 사용하여 execvp()을 호출하여 시작됩니다. 작업이 끝나면 에 대한 신호 처리기가 있습니다.이 프로세스에서는 방금 종료 된 프로세스를 확인하기 위해 wait()을 수행합니다. exe1이 끝나면 종료 코드를 관찰하고 exe2을 시작할지 여부를 결정합니다.

내 관심사는 어떻게 시작합니까 exe2입니다. 내 SIGCHLD 처리기의 컨텍스트에서 내 jobManager 시작 함수를 사용하면 너무 많은 SIGCHLD 처리기 함수 (예를 들어, 10 조건부 실행 있었다면)에 놀고 결국 수도 결국 우려하고있다. 또한 간접적으로 발생하는 경우에도 신호 처리기에서 다음 실행을 시작하는 것이 좋지 않은 것처럼 보입니다. (1.5 년 전 신호 처리에 대해 배웠을 때 비슷한 것을 시도해 보았습니다.

위의 모든 내용이 백그라운드에서 발생할 수 있어야하며 jobManager이 바쁜 대기 상태가되어 exe1이 반환되기를 기다리는 것을 피하고 싶습니다. 또한 다른 프로세스의 실행을 시작하기 위해 대기하는 별도의 스레드가없는 것이 좋습니다. 그러나 내 jobManager에게 SIGCHLD 처리기에서 다음 프로세스의 실행을 시작하도록 지시하는 것은 좋지 않은 코드처럼 보입니다.

모든 의견이 적합합니다.

답변

1

나는 두 가지 방법을 참조 당신의 프로그램은 파이프 핸들에서 "select"를 사용하여 이벤트를 기다립니다. 신호 처리기에서 파이프에 쓰기 및 mainloop 핸들 상황에서.

+0

아 - select() 솔루션은 나에게 매우 흥미 롭습니다. 나는 소켓 프로그래밍에서 select()/poll()을 사용했고 바쁜 대기를 피하기 위해 여기에서 비슷한 것을하기를 희망했다. 그러나 런타임시 신호 처리기에 아무 것도 제공 할 수 없기 때문에 파이프가 '전역'이어야한다고 생각합니다. – BSchlinker

+0

sigwait 루프는 추악하며 배경 작업이 필요하기 때문에 여기서는별로 도움이되지 않습니다. – Robert

+1

당신은이 전역 변수를 wihtout으로 처리 할 수 ​​있습니다. 그러나 리눅스의 특별한 방법으로 : signalfd는 신호에 대한 정보를 얻는 기술자를 생성합니다. – fghj

0

음, 그거 좋네.

프로세스마다 한 번, 두 번 분기하는 것은 어떻습니까? 첫 번째는 실행되고 두 번째는 중지됩니다. 부모 SIGCHLD 핸들러에서 두 번째 자식에게 SIGCONT를 보낸다. 두 번째 자식은 적절하다면 꺼내서 작업을 실행한다. 당연히, 첫 번째 것이 실행되어서는 안되면 두 번째 경고를합니다. 아무 것도 설정하지 않았으므로 안전해야합니다.

어떻게 들리는가요? 아무 것도하지 않고 앉아있는 과정을 갖게 될 것이지만 오랜 시간 동안해서는 안됩니다. (시작하기 전에 파이프를 만드는)
다음

2 루프
에) 사람이 3 sigwait를 참조, 그리고 돌이에
1) 당신이 "sigwait"전화 루프 sighandler 교체 :

+0

나는이 솔루션을 피하고 싶습니다. 내 관점에서 볼 때 리소스가 불행한 것처럼 보였기 때문입니다. 또한 작업 내에서() 루프와 같이 처리 할 수있는 고급 상황이 있습니다. – BSchlinker

+0

@BSchlinker 당신의 자식 프로세스가 많은 일을하지 않는 한 그것은 실제로 자원 낭비가 아닙니다.fork()는 copy-on-write이므로 대기 프로세스에서 KB 정도가 사용됩니다. 차단 될 것이므로 CPU 시간이 필요 없습니다. – Robert