2014-06-24 3 views
1

나는 복수 스레드가 동기화 된 방식으로 요소를 하나씩 선택하는 전역 std::queue을가집니다. 큐는 구조체입니다. 사본을 만들기 : (다른 스레드가 .front()를 호출하여 다음 요소를 얻을 수 있도록)std : queue에서 요소를 분리하는 방법

각 스레드 호출 .front()

문제 첫 번째/다음의 요소의 취득과의 로컬 복사본을 만들고 큐에서 다음 .pop()을합니다 의 요소는 성능에 영향을줍니다.

큐를 구성하는 요소가 분리되어 있습니까? (대기열에 더 이상 포함되지 않도록하고 동시에 삭제되지 않습니다. 발신자가 삭제 처리합니다.)

+1

이동할 수 있습니다. – chris

+0

@chris 답변을 작성하십시오 (죄송합니다, 이전 의견에 대해서는'priority_queue'와 섞어 놓았습니다) – Angew

+0

OOps 예. 방금 대기열 방법을 살펴본 결과 아무 것도 찾지 못했습니다. 롤. 감사. – Atul

답변

5

요청한 대기열 작업이 없습니다. 대안 :

  • 구조를 이동 가능하게 만듭니다. front()에서 이동하고 나서 pop() 이동 된 대상에서 이동하십시오. 구조가 매우 큰 경우 (예 : 멤버로 큰 배열이있는 경우) 객체 자체의 내용을 계속 복사해야하므로 이동 속도가 느려질 수 있습니다. 그러나 구조가 string 회원으로 인해 복사하는 데 비용이 많이 든다면 이동하는 것이 더 저렴할 것입니다.
  • 실제 데이터에 대한 스마트 포인터 큐를 사용하십시오. 스마트 포인터를 복사하는 것은 매우 저렴하므로 전체 개체를 복사하지 않아도 성능 요구 사항을 충족시킬 수 있습니다.
  • 대기열을 사용하는 대신 소비자 스레드가 사용하는 다른 목록에 listsplice() 프런트 요소를 사용하십시오. 스레드가 처리되면 스레드 별 목록에서 제거하십시오. 나는 이것을 정말로 추천하지는 않지만 실제로 컨테이너에서 물체를 분리하는 것이 가장 가까운 것이기 때문에 언급한다. 그것은 원래 목록에서 분리되었지만 을 다른 목록에 동시에 다시 첨부해야합니다.
+0

** 똑똑한 포인터의 Regd 사용 : ** 스택에 생성 된 구조가 대기열로 바로 복사됩니다. 힙에 복사본을 만드는 것은 오버 헤드가됩니다. ** 목록 ** 목록을 사용하여 Regd가 내 요구 사항에 맞지 않습니다. 나는 목록에서'큐'로 옮겼다. ** Regd moving ** 실제로 움직이면, 현재 내가하고있는 것과 같지 않은가? – Atul

+0

@Andrew "힙의 복사본"은 "큐의 복사본"보다 오버 헤드가 더 큽니까? 스택의 복사본을 처음부터 만들 필요조차 없습니다. 그리고 move에 관한 예 :'std :: vector'를 복사하는 것은 벡터의 전체 내용을 복사합니다. 'std :: vector'를 옮기면 실제적으로'std :: vector' 객체 안에 저장된 3 개의 포인터 (또는 구현에 기반한 비슷한 것)를 복사합니다. 차이점을 보시겠습니까? – Angew

+0

@Angew : Sry 전 결코 이사 한적이 없습니다. 왜냐하면 스티브가 말한 이유는 객체 자체의 내용이 여전히 복사되어야하기 때문입니다. ** 나는 혼란스러워했습니다. 그러나 나는 당신이 말한 것을 토대로이 옵션을 탐색 할 것입니다. – Atul

0

std::queue은 일반적으로 링크 된 목록이 아닙니다. 요소들 (또는 적어도 요소들의 블록들)은 연속적이다. 복사가 문제라면 포인터 큐를 사용할 수 있습니다. 나는 과거에 성공 했으므로 std::unique_ptr (실제로는 std::auto_ptr)을 사용하여 동적으로 할당 된 포인터의 큐를 사용하여 성공적으로 성공했습니다.

+0

나는 (특히'new'를 사용하여)이 배열을하고 있었지만 메모리 조각화와 다른 문제 때문에 컨테이너가 나를 위해 그것을 할 수 있도록 할 계획이다 (컨테이너가 청크 등으로 할당 할 때). 그래서 저는 스택에 객체를 생성하고 그것을 큐에 전달합니다. – Atul

+0

@Andrew 메모리 조각화가 유일한 이유 인 경우 개체에 대한 풀 할당자가 최상의 솔루션 일 수 있습니다. –

+0

고마워요. 풀 할당자를 처음 사용했습니다. 예제를 보여주는 링크가있어서 빨리 가져올 수 있습니다. (요약하면 가능한 한 코드에서'new'를 제거하려고 노력하고 있습니다.) – Atul

관련 문제