2009-08-05 5 views
19

프로그램에서 혼합 및 스레딩을 혼합하는 것은 매우 문제가 될 수 있으며 종종 잠금 장치, 파이프, 파일 설명자와 같은 공유 리소스를 처리 할 때 신비한 동작을 초래할 수 있다고 들었습니다. 그러나 나는 위험이 정확히 무엇인지, 언제 일어날 수 있는지 정확히 이해하지 못합니다. 이 분야의 전문 지식을 가진 사람이 함정이 무엇인지, 그러한 환경에서 프로그래밍 할 때주의해야 할 점에 대해 더 자세히 설명 할 수 있다면 좋을 것입니다.다중 스레드 프로그램에서 분기

예를 들어 다양한 리소스의 데이터를 수집하는 서버를 작성하려면 서버에서 스레드 집합을 생성하고 각 서버가 실제 프로그램을 호출하도록 호출하는 것이 좋습니다. 일하고, 파이프를 열어 어린이에게서 데이터를 다시 얻으십시오. 이 스레드는 각각 자신의 작업에 응답하고 데이터를 교환하지 않으며 데이터를 수집 할 때 주 스레드에 대기열이 있으며 작업자 스레드는 결과를 대기열에 넣습니다. 이 솔루션으로 무엇이 잘못 될 수 있습니까?

예제 시나리오에 "답변"하여 답변 범위를 좁히지 마십시오. 예제와 관련이 없지만 깔끔한 디자인을 제공하는 데 도움이되는 제안, 대체 솔루션 또는 경험은 유용 할 것입니다. 감사!

+0

주제에 대한 자세한 내용은 [잘 읽음] (http://thorstenball.com/blog/2014/10/13/why-threads-cant-fork/)입니다. –

답변

0

정말 간단합니다. 다중 스레드 및 프로세스의 문제점은 항상 공유 데이터에서 발생합니다. 공유 데이터가 없으면 발생할 수있는 문제가 없습니다.

예에서 공유 데이터는 주 스레드가 소유 한 대기열입니다. 잠재적 인 경합 또는 경쟁 조건이 여기에서 발생합니다. 이러한 문제를 "해결하는"일반적인 방법은 잠금 스키마와 관련이 있습니다. 작업자 스레드는 데이터를 삽입하기 전에 대기열을 잠그고 주 스레드는 제거하기 전에 대기열을 잠급니다.

+0

malloc 메타 데이터는 "공유 된 데이터"? :) – bdonlan

+0

모르겠다.하지만 보통은 표준 라이브러리가 쓰레드 안전 (쓰레드 안전 버전을 선택해야 할 때가있다)과 같은 방식으로 작성된다. 공유 데이터의 정의와 영향에 따라 다릅니다. –

+0

종종 데이터를 공유하는 것을 피할 수 없습니다. 파이프, 파일 설명자 등. 항상 포크에서 공유됩니다. 이제 리눅스에서, 하나는 O_CLOEXEC 플래그를 설정할 수 있습니다. 그래서 fork를 할 때 fd를 닫을 수 있습니다. (나는 그 의미가 자식 주소 공간의 fd를 닫습니다.) 스레드를 추가하면 도움이 될지 모르지만 ? 예 : 하나의 스레드와 포크로 파이프를 열면 어떻게 될까요? 다른 스레드에서도 포크를 수행하면 어떻게됩니까? 어떤 아이가 파이프를 볼 수 있을까요? – jimx

16

일부 스레드가 실행 중일 때 분기 할 때의 문제점은 fork를 호출 한 스레드의 CPU 상태 만 복사한다는 것입니다. 모든 스레드가 방금 죽었을 때마다 즉각적으로 그럴 수 있습니다.

결과적으로 잠금이 해제되지 않으며 공유 데이터 (예 : malloc 힙)가 손상 될 수 있습니다. 이론적으로, 당신은 분기 전에 프로그램의 모든 잠금을 한 후이를 해제하고, 어쩌면 그것을 밖으로 살아 만들 수 - -

는 pthread는 pthread_atfork 기능을 제공하지 않습니다하지만 당신은 항상 하나를 놓칠 수 있기 때문에, 위험 해. 물론 다른 스레드의 스택은 해제되지 않습니다.

+0

'잠금 장치가 해제되지 않았다'는 것이 무슨 뜻인지 조금 더 자세히 설명해 주시겠습니까? 아이의 관점에서 볼 때 옳은가? 그래서 아이는 결코 자물쇠를 얻을 수 없습니까? – jimx

+0

수정하십시오. 포크 복제본은 여전히 ​​잠긴 상태에있는 동안 모두 잠급니다. – bdonlan

관련 문제