간단한 개체 (레코드) 형태로 데이터를 생성하는 스레드가 있습니다. 스레드는 필터를 성공적으로 통과하고 실제로 대기열에 포함 된 각각에 대해 1,000 개의 레코드를 생성 할 수 있습니다. 객체가 대기열에 추가되면 해당 객체는 읽기 전용입니다..NET의 이중 대기열 생성자 - 소비자 (강제 멤버 변수 flush)
레코드가 필터를 통과하면 획득하는 잠금이 하나 있습니다.이 항목을 producer_queue의 뒤에 추가합니다.
소비자 스레드에서 잠금을 획득하고 producer_queue가 비어 있지 않은지 확인하고 이 consumer_queue를 producer_queue와 같게 설정하고 새 (빈) 큐를 생성 한 다음 producer_queue에서 설정합니다. 추가 잠금이 없으면 empty와 repeat가 될 때까지 consumer_queue를 처리합니다.
모든 것이 아름답게 대부분의 컴퓨터에서 작동하지만 특정 듀얼 쿼드 서버에서는 ~ 1/500k 반복에서 consumer_queue를 읽을 때 완전히 초기화되지 않은 개체가 표시됩니다. 조건은 매우 가볍기 때문에 조건을 감지 한 후 객체를 덤프 할 때 필드의 90 %가 올바른 것입니다.
내 질문은 이것입니다 : 개체에 쓰기가 대기열을 바꿀 때 주 메모리로 플러시되도록하려면 어떻게해야합니까?
편집 : 제조자 스레드
: (위 producer_queue가 m_fillingQueue이다 consumer_queue 위에서 m_drainingQueue이다) 소비자 글
private void FillRecordQueue() {
while (!m_done) {
int count;
lock (m_swapLock) {
count = m_fillingQueue.Count;
}
if (count > 5000) {
Thread.Sleep(60);
} else {
DataRecord rec = GetNextRecord();
if (rec == null) break;
lock (m_swapLock) {
m_fillingQueue.AddLast(rec);
}
}
}
}
는 :
private DataRecord Next(bool remove) {
bool drained = false;
while (!drained) {
if (m_drainingQueue.Count > 0) {
DataRecord rec = m_drainingQueue.First.Value;
if (remove) m_drainingQueue.RemoveFirst();
if (rec.Time < FIRST_VALID_TIME) {
throw new InvalidOperationException("Detected invalid timestamp in Next(): " + rec.Time + " from record " + rec);
}
return rec;
} else {
lock (m_swapLock) {
m_drainingQueue = m_fillingQueue;
m_fillingQueue = new LinkedList<DataRecord>();
if (m_drainingQueue.Count == 0) drained = true;
}
}
}
return null;
}
소비자는 속도이며 제한적이므로 소비자보다 앞서 나갈 수 없습니다.
내가 보는 동작은 때때로 Time 필드가 DateTime.MinValue로 읽는 것입니다. 그러나 예외를 던질 문자열을 구성 할 때까지는 아무 문제가 없습니다.
명확하지 않습니다. 생산 대기열에서 소비자 대기열과 동일한 변수를 사용하고 있다는 말씀입니까? 그것은 저에게 두드러지는 유일한 작품입니다. 일부 샘플 코드가 도움이 될 수 있습니다. –
잠금에 대한 설명에 따라 'consumer_queue'가 불완전하게 초기화 된 객체를 포함 할 수있는 방법을 알 수 없습니다. 이 질문에 대한 코드 조각을 게시 할 수 있습니까? – jerryjvl