한 번에 허용되는 인스턴스의 동시 실행 수를 제어하는 래퍼를 만들려고합니다. 그렇게하기 위해, 나는 시스템 전체 세마포어를 사용하고있다. 세마포어를 만들고 sem_wait()
을 실행하고 자식 프로세스를 시작한 다음 자식이 종료되면 sem_post()
을 수행합니다. 괜찮습니다.sem_wait()/sem_post()의 신호 안전한 사용
문제는이 래퍼로 보낸 신호를 안전하게 처리하는 방법입니다. 신호를 포착하지 않으면 명령이 sem_post()
을하지 않고 종료되어 세마포어 수가 영구적으로 1 씩 감소합니다. 그래서 sem_post()
을 수행하는 신호 처리기를 만들었습니다. 그러나 여전히 문제가 있습니다. 핸들러가 sem_wait()
전에 연결된 경우
sem_wait()
없이 발생하는
sem_post()
을 일으키는
sem_wait()
완료되기 전에 도착할 수 행한다. 신호 처리기를 설정하기 전에
sem_wait()
을 수행하면 그 반대가 가능합니다.
명백한 다음 단계는 핸들러와 sem_wait()
의 설정 중에 신호를 차단하는 것이 었습니다. 이것은 내가 지금 무슨의 의사입니다 :
void handler(int sig)
{
sem_post(sem);
exit(1);
}
...
sigprocmask(...); /* Block signals */
sigaction(...); /* Set signal handler */
sem_wait(sem);
sigprocmask(...); /* Unblock signals */
RunChild();
sem_post(sem);
exit(0);
문제는 이제 sem_wait()
차단할 수 있으며, 그 시간 동안, 신호가 차단되어 있다는 점이다. 프로세스를 죽이려하는 사용자는 "kill -9"에 의존하게 될지도 모릅니다. 이는 내가 어떤 경우이든 상관없이 내가 격려하고 싶지 않은 행동입니다. sem_trywait()
을 잠시 사용하고 sigpending()
을 테스트 할 수는 있지만 더 긴 세마포어를 기다리는 프로세스가 다음에 실행될 것이라는 보장이 없기 때문에 공정성에 영향을 미칩니다.
세마포어 수집 중에 신호를 처리 할 수있는 안전한 솔루션이 있습니까? 나는 "세마포어를 가지고 있습니까?"라고 생각하고 신호 차단을 제거하는 것을 고려하고 있습니다.하지만 세마포어를 획득 한 이후 100 % 안전하지는 않습니다. 전역 설정은 원자가 아니지만 대기 중에 신호를 차단하는 것보다 낫습니다.
내가 불분명하면 죄송합니다.sem_wait()는 말한대로 신호를 차단하지 않지만 sigprocmask()를 사용하여 차단합니다. 하지만, 당신은 핸들러가 종료해서는 안되지만 "종료 할 시간"을 말하는 플래그를 설정해야한다는 것을 의미하는 EINTR 에러 코드를 살펴 보는 것이 올바른 해결책이라고 생각합니다. 나는 그것을 시험 할 것이다. 감사. – Jeremy
그게 효과가 있어요. 신호 차단을 제거하고 신호 처리기를 변경하여 종료 할 때의 전체적인 의미를 설정했습니다. sem_wait()가 에러를 리턴하면, 나는 끝내고 세마포어 카운트를 보존한다. 아이를 기다리고 있으면 timeToQuit도 테스트합니다. 종료 할 시간이되면 자식을 죽이고 세마포어 수를 유지하는 sem_post()를 수행합니다. 감사. 그것은 kill -9를 무시하고 신호 안전해야합니다. – Jeremy