2009-07-05 3 views
11

단일 생산자 - 단일 소비자에 대해서는 여러 구현을 발견했지만 여러 생산자 - 단일 소비자에 대해서는 구현이 없습니다.Delphi에서 lock-free 큐 "다중 생성자 - 단일 소비자"가 존재합니까?

"다중 생성자 - 단일 소비자"에 대한 잠금없는 대기열이 Delphi에 있습니까?

+1

잠금없는 알고리즘과 대안을 사용하는 성능 튜닝에 대한 매우 흥미로운 대답은 다음과 같습니다. http://stackoverflow.com/questions/853316/is-critical-section-always-faster/853510#853510. – mghie

답변

5

OmniThreadLibrary의 잠금없는 대기열은 여러 생성자를 지원합니다. 스레딩 라이브러리와 별도로 사용할 수 있습니다 (즉, 다른 모든 프레임 워크에서 OtlContainers 단위를 사용할 수 있음).

Daniele이 아래에서 지적했듯이 OmniThreadLibrary에는 두 개의 대기열이 있습니다. OtlContainer의 제품은 여러 생산자와 다수의 소비자를 지원하지만 OtlComm의 "더 똑똑한"버전 (단순한 버전의 포장지)은 단 하나의 생산자/단일 소비자입니다.

문서는 여전히 큐에 대한 일부 정보가 here 발견 될 수있다. OmniThreadLibrary 프로젝트 :(의 큰 문제입니다. 여러 생산자/단일 소비자 대기열/FIFO, 당신은 쉽게 만들 수있는 하나의 LockFree를 들어

+0

정말요? 당신의 목록을 사용했지만 소스 코드는 저에게 "슬픈"코멘트입니다 ... "{: 잠금 장치가없는 단일 기록 장치, 단일 판독기 링 버퍼. OtlComm에서 } IOmniQueue = 인터페이스 [ '{AE6454A2-CDB4-43EE-9F1B-5A7307593EE9}'] 높은 수준을 " 당신은 OmniQueue은, 단일 소비자가, 내 실수를? –

+0

죄송 가능. MULTI 생산자이라고 말할" "큐 단일 생산자/단일 소비자입니다. OtlContainers의 "하위 수준"대기열은 여러 생산자/다중 소비자입니다. 따라서 여러 생산자를 사용하려는 경우 더 간단한 대기열 객체 변형을 사용해야합니다. 위 텍스트를 다음과 같이 고정했습니다. 올바른 장치 이름을 참조하십시오. – gabr

3

도움이 될 수도 있습니다 : Interlocked SList functions.

+0

+1. 응용 프로그램이 XP 이전 Windows 시스템에서 작동해야하는 경우이 대안을 구현해야합니다. 비어있는 큐에 소비자 블록을 두는 쉬운 방법이 없다는 것에도 유의하십시오. – mghie

+0

SList 함수는 큐가 아닌 스택을 생성합니다. –

+2

@Rob Kennedy : 소비자가 InterlockedPopEntrySList() 대신 InterlockedFlushSList()를 사용하면 목록 항목을 양방향으로 처리 할 수 ​​있습니다. – mghie

2

http://svn.berlios.de/svnroot/repos/dzchart/utilities/dzLib/trunk/lockfree/

@Daniele 테티 :

독자는 여전히 인큐 방법을 종료합니다 이전 큐에 액세스 할 수있는 모든 작가 기다려야합니다. 독자가 Dequeue 메소드에서 수행하는 첫 번째 작업은 Enqueue를 입력하는 새 작성자를위한 새로운 대기열을 제공하기 때문에 이전 대기열을 참조하는 모든 작성자가 Enqueue를 종료하는 데 오랜 시간이 걸리지 않아야합니다. 그러나 당신은 맞습니다. 그것은 작가에게만 잠금이 해제되어 있지만 독자 스레드가 일부 작성자가 Enqueue를 종료 할 때까지 기다려야 할 수도 있습니다.

+1

이 목록을 사용하고 있지만 ... "LockFree"목록에 대한 코드 주석이 이상합니다. "// 불행히도 다른 스레드가 이전 큐에 여전히 // 참조를 보유 할 수 있습니다. // 우리가 ActiveWriters가 //이 저하 을 계산 할 때까지 기다릴 필요가 100 % 확실하게 0 // 현재 작가가 있다면, 우리는 를 감소 최초의 작가에 의해 설정됩니다 // 경우 대기// ActiveWriters 0으로 기다릴 필요가 없다면. " 이것은 일종의"대기 "sinchronization 것 같습니다 ... 내가 틀렸어? (나는이 주석 TMultiWriteSingleReadLockFreeQueue.Dequeue 내부에서 찾았습니다.) –

2

SLIST 나 사소한 Lock Free LIFO 스택을 사용한다. 당신이하는 일은 소비자를위한 두 번째 "개인용"스택을 갖는 것이다 (단순화를 위해 SLIST 또는 선택할 수있는 다른 스택 모델로도 수행 할 수있다). 개인 LIFO가 폭발 할 때마다 공유 SLIST 체인을 포착하지 않고 플러시 (플러시 전체 SLIST 체인 잡기) 한 다음 플러시 된 목록을 순서대로 보면서 항목을 개인 스택에 푸시합니다.

단일 제작자/단일 소비자 용 및 다중 제작자/단일 소비자 용으로 작동합니다.

그러나 여러 제작자/여러 소비자의 경우에는 작동하지 않습니다.