2012-06-01 4 views
1

다음을 수행 할 계획입니다.생산자/소비자 패턴에 대한 STL 컨테이너 스레드 안전성

소비 될 사전 빌드 된 객체의 큐를 저장합니다. 주 스레드는이 오브젝트들을 여기 저기에 소비 할 수 있습니다. 로깅에 사용되는 또 다른 쓸데없는 스레드가 있으며 시간이 많이 걸리지 않지만 값 비싼 것들은 아닙니다. 미리 만들어진 객체가 부족할 때, 나는 그들을 쓸데없는 스레드로 채워 넣을 것입니다.

이제 제 질문은 경쟁 조건이 될 것입니까? 기술적으로 한 스레드가 앞쪽에서 객체를 사용하고 있고 다른 스레드가 객체를 뒤에서 밀어 넣고 있습니다. 크기를 0으로 줄이지 않는 한 괜찮습니다. 걱정되는 유일한 점은이 양면 큐의 "크기"입니다. STL 컨테이너에 정수 "크기"변수를 저장합니까? 그 크기 변수를 수정하면 경쟁 조건이 생겨날까요?

이 문제를 해결하는 가장 좋은 방법은 무엇입니까? 주 스레드가 성능에 치명적이기 때문에 잠금을 사용하고 싶지 않습니다. (처음에이 개체들을 사전 구축 한 이유입니다!)

답변

4

또 다른 옵션은 2 개의 퀴 올드 (deques)를 갖는 것입니다. 메인 쓰레드는 읽는다. 읽기 양단 큐가 비어있는 경우, 잠금을 포함하지만 가끔씩 만 (두 포인터 이동) dequees를 전환하십시오. 이 전환 할 때 잠금을 할 필요가 있으므로

소비자 스레드는 스위치를 구동한다. 제작자 쓰레드는 쓰기 도중에 스위치가 발생할 경우를 대비하여 쓰기마다 잠글 필요가 있습니다.하지만 소비자가 언급하는 것처럼 성능이 중요하지 않으므로 걱정할 필요가 없습니다.

자물쇠가 없다는 것은 다른 사람들의 언급처럼 실제로 위험합니다.

+0

-1 스위치가 발생할 때 소비자 스레드가 대기열에서 읽는 중일 때는 어떻게 될까요? 이를 방지하기 위해서는 전체 읽기를 보호해야합니다. 전체 아이디어를 거의 무시합니다. 전환하는 동안 글쓰기 중일 수도있는 제작자 용 Ditto. –

+0

@BrankoDimitrijevic, 그렇기 때문에 독서 대기열이 비어있을 때까지 기다린 후 *** 스위치를 차단하십시오. 생산자 쓰레드가 성능에 치명적이지 않다면 (OP와 유사), 각 쓰레드를 차단할 수 있습니다. 스위치는 소비자에 의해 구동됩니다. – Brady

+0

이제 알겠습니다.downvote에 대한 미안 해요 - 당신은 내가 그것을 되돌릴 수 있도록 답변을 편집 할 수 있습니까? –

8

STL 컨테이너는 스레드로부터 안전하지 않으며 기간은 재생되지 않습니다. 이. 특히 deque 요소는 일반적으로 짧은 배열의 체인에 저장되며 해당 큐가 비 큐와 함께 작동 할 때 수정되므로 사물을 엉망으로 만들 수있는 많은 공간이 있습니다.

0

deque이 비어있는 경우에도 데이터 경쟁이 있습니다.

잠금을 통해 deque에 대한 모든 액세스 (쓰기 만)를 보호하거나 멀티 스레드 환경 (예 : Microsoft의 unbounded_buffer)에서 소비자 생성자 모델 용으로 특별히 설계된 대기열을 사용해야합니다.

1

@sharptooth에서 언급했듯이 STL 컨테이너는 스레드로부터 안전하지 않습니다. C++ 11 가능 컴파일러를 사용하고 있습니까? 그렇다면 원자 유형을 사용하여 잠금없는 큐를 구현할 수 있습니다. 그렇지 않으면 비교 - 교환을 위해 어셈블러를 사용하거나 플랫폼 특정 API (here 참조)를 사용해야합니다. 이를 수행하는 방법에 대한 정보를 얻으려면 this question을 참조하십시오.

표준 스레드 동기화를 사용할 때 성능을 측정하고 실제로 잠금없는 기술이 필요한지 확인해야합니다.