2011-03-29 2 views
4

pthread_atfork 용 표준 관용법은 프리 - 포크 핸들러의 모든 잠금을 획득하고 상위 핸들러와 하위 핸들러 모두에서이를 해제하는 것으로 가정됩니다. 그러나 내가 알 수있는 한, 이것은 불가능합니다. pthread_mutex_unlock은 호출 스레드가 뮤텍스의 소유자가 아닌 경우 (정상 또는 기본 유형 뮤텍스의 경우) 정의되지 않은 동작을하거나 (재귀 또는 오류 검사 뮤텍스의 경우) 실패하도록 지정됩니다. pthread_atfork으로 등록 된 하위 처리기에서 호출하는 스레드는 새로 생성 된 프로세스의 주 스레드이므로 뮤텍스의 소유자가 될 수 없습니다.pthread_atfork 잠금 관용구가 깨졌습니다?

내가 실수로 사용하거나 전체적으로 pthread_atfork 관용구가 디자인 상 깨졌으며 본질적으로 사용이 불가능합니까?

편집 : 또한이 문제에 대한 유효한 (휴대용) 해결 방법을 찾지 못했습니다. 뮤텍스가 POD가 아니고 일부 커널 레벨 객체에 대한 참조를 포함하는 어리석은 구현을 수용하기 위해 초기화 된 뮤텍스에 대한 pthread_mutex_destroy 호출이 정의되지 않은 동작으로 지정된다는 점을 제외하고는 아이 프로세스에서 뮤텍스를 파괴하고 다시 초기화하는 것이 이상적입니다. .

답변

1

나는이 사람의 관련 텍스트 생각 :

포크()가 호출

호출 스레드가 자식 프로세스에 복제됩니다. 동기화 변수 은 자식에서 동일한 상태로 남아 있으며, fork()가 호출 된 시간은 에있는 부모에있었습니다. 따라서 예제의 경우 자식 프로세스에서 더 이상 존재하지 않는 스레드가 mutex 잠금을 보유 할 수 있으며 연결된 상태는 일치하지 않을 수 있습니다. 부모 프로세스는 pthread_atfork()를 통해 자식 자식에게 중요한 잠금을 획득하고 해제하는 코드 인 코드를 피할 수 있습니다. 또한 중요한 스레드 을 다시 작성하고 자식의 적절한 상태 에서 으로 다시 초기화해야합니다 (pthread_atfork()를 통해서도 가능).

자식에서 atfork 처리기를 실행하는 스레드는 atfork 준비 처리기를 부모에서 실행 한 스레드와 동일하므로 뮤텍스를 잠금 해제 할 수 있습니다.

+1

설득력이 없습니다. "정확한 사본"(필자는 이것이 정확하지 않고 스펙에 나타나지 않기 때문에 이것을 인용 부호로 붙였습니다)이 동일한 스레드라는 것을 의미하지는 않습니다. 또한 강력하고 프로세스 공유 된 뮤텍스의 의미는 뮤텍스에 대한 "소유자"의 개념이 포크간에 유지 될 수있는 프로세스 내부 ID가 아니어야 함을 명확하게합니다. –

+0

궁극적으로, 뮤텍스가 소유자를 저장하는 방법에 따라 다릅니다. 소유자가 스레드 ID로 표시되면 오른쪽 스레드 ID (Linux 이상)가 전 세계적으로 고유합니다. 소유자가 일부 스레드 헤더에 대한 포인터로 표시되면 fork가 올바른 작업을 수행합니다. 후자가 의심 스럽습니다. – Arkadiy

+0

적어도 프로세스 공유 뮤텍스의 경우 소유자는 일부 전역 고유 식별자로 저장해야합니다. 비공유 뮤텍스 (단지 일관성과 구현의 단순함)를 위해서 같은 것을하는 것이 합리적이다. 실제로 glibc/NPTL은이 목적을 위해 커널 thread-id를 사용한다. 어쨌든 내 질문은 이것이 POSIX 쓰레드 스펙의 결함인지 아닌지에 관한 것이므로 어떤 구현이 "옳은 일"을하더라도 도움이되지 않으며 실제로 그렇게함으로써 스펙을 위반할 수도있다. –

관련 문제