그래서 나는 입력 데이터를 제공하는 많은 스레드를 가지고 있는데, 이는 도착 순서에 따라 하나의 스레드에 의해 처리되어야합니다. 현재 모든 입력 항목은 대기열에 삽입되고 대기열에 대한 읽기/쓰기는 C# lock 문으로 보호됩니다. 그러나 시간이 지남에 따라 응용 프로그램의 CPU 사용량이 허용 할 수없는 수준으로 올라가고 프로필러는 대부분의 CPU 시간이 잠금 문 자체에 소비되고 있다고 말합니다. 자물쇠 대신 많은 작가와 독자를 지원하는보다 효율적인 동기화 방법이 있습니까?많은 작성자를위한 가장 효율적인 잠금 단일 판독기 동시성 모델?
답변
작가들이 자물쇠로 서로 경쟁하고있는 것처럼 들립니다. 각 작성자가 고유 한 대기열을 갖고 있고 독자가 Peek method을 사용하여 각 대기열의 첫 번째 메시지를 제거하지 않고 읽는 모델을 생각해보십시오. 그런 다음 독자는 대기열 간 반복을 유지하고 각 대기열의 첫 번째 항목 세트 중 첫 번째 항목을 엿보고 첫 번째 항목을 제거 및 처리 할 수 있습니다. 현재 아키텍처보다 느려지지만 작성자 간의 잠금 경합을 제거해야합니다.
같은 예제이다 보일 수 있습니다 그것은 당신의 응용 프로그램에 큰 변화 될 수
public class TimestampedItem<T> : IComparable<TimestampedItem<T>>
{
public DateTime TimeStamp { get; set; }
public T Data { get; set; }
public int CompareTo(TimestampedItem<T> other)
{
return TimeStamp.CompareTo(other.TimeStamp);
}
}
public void ReadFirstFromEachQueue<T>(IEnumerable<Queue<TimestampedItem<T>>> queues)
{
while (true)
{
var firstItems = new List<TimestampedItem<T>>(queues.Select(q => { lock (q) { return q.Peek(); } }));
ProcessItem(firstItems.OrderBy(tsi => tsi.TimeStamp).First());
}
}
}
,하지만 당신은 (예를 MSMQ에 대한) 응용 프로그램에 외부 대기열을 고려할 수 있습니다 다음, 당신이 할 수 귀하 작가 스레드가 대기열에 자신의 마음에 내용을 쓰고 있습니다. 그러면 독자가 준비가 완료되면 항목을 꺼낼 수 있습니다. CPU 시간의 대부분이 대기열 주변의 잠금 장치에있는 경우 (실제로 대기열에있는 항목에 대한 작업을 잠그지 않은 것으로 가정), 대기열을 응용 프로그램에 넣으면 실제로 도움이 될 수 있습니다. 이상적으로는 쓰기와 읽기를 분리 된 프로세스로 분리 할 수도 있습니다.
또 다른 한가지는 잠그고있는 객체가 앱의 다른 부분을 잠그는 데 사용되지 않는다는 것입니다. 모니터 (lock 문 뒤에있는 것)는 아마도 가장 가벼운 가중치 스레드 동기화 방법 일 수 있으므로 아이템을 처리하는 동일한 프로세스에서 잠금을 피하기 위해 사물을 다시 설계하는 것이 가장 좋습니다.
당신이 다음 대신 정상 Queue
의, ConcurrentCollections
의 일부입니다 ConcurrentQueue
을 사용하고 큐에 데이터를 읽기/쓰기 할 때 잠금 제거 할 수 4.0
당신이 .NET 버전을 사용하는 경우 ConcurrentCollections
은 당신은 당신이 할 수있는 4.0
를 사용하지 않는 경우 ..
을/동시 읽기를 처리 잠금 무료로 코드를 작성하는 데 사용할 수 있도록 설계하는 것은 다른 잠금이 굽없는 경우, 당신은 달성 할 수있는 유일한 고정하는 것입니다 메모를 Monitor.TryEnter
를 사용하는 대신 lock
로 그 lock
자체는 Monitor.Enter
과 Monitor.Exit
의 조합입니다, 샘플 구현은 다음과 같습니다 :
private readonly object _syncObject = new object();
private bool TryUpdate(object someData)
{
if (Monitor.TryEnter(_syncObject))
{
try
{
//Update the data here.
return true;
}
finally
{
Monitor.Exit(_SyncObject);
}
}
return false;
}
- 1. Clojure에서 다중 판독기/단일 작성자를위한 스레드 동기화
- 2. MS SQL 동시성, 초과 잠금
- 3. Java EE 동시성 및 잠금
- 4. 계층 구조 및 판독기 기록기 뮤텍스 잠금
- 5. 공유 리소스에 대한 가장 빠른 다중 판독기/단일 작성기 보호 -
- 6. 효율적인 트랜잭션, 레코드 잠금
- 7. 많은 양의 데이터를 내보내는 가장 효율적인 방법
- 8. 얼랭 동시성 모델
- 9. nodejs의 동시성 모델
- 10. 많은 뮤텍스 잠금 사용
- 11. 잠금 비즈니스 모델
- 12. Java 동시성 잠금 및 조건 사용
- 13. C# WinForm 호출과 동시성
- 14. 많은 모델 중 하나에 속하는 모델에 접근하는 가장 좋은 방법
- 15. 가장 효율적인 쿼리는 무엇입니까?
- 16. 가장 효율적인 스키마
- 17. PHP에서 단일 문자가 영숫자인지를 확인하는 가장 효율적인 방법은 무엇입니까?
- 18. 동시성 제어
- 19. 많은 작은 할당에 대해 가장 효율적인 malloc 구현은 무엇입니까?
- 20. SQL Server에 많은 문자열 메시지를 저장하는 가장 효율적인 방법은 무엇입니까?
- 21. 방법/가장 효율적인 방법으로 많은 사용자에게 메시지를 보냅니 까?
- 22. BerkeleyDB 동시성
- 23. 링크 테스트를위한 가장 효율적인 방법
- 24. 액션 스크립트 3 (AS3) 동시성 모델
- 25. 단일 스레드 모델
- 26. 장고는 가장 효율적인 방법입니까?
- 27. 가장 효율적인 방법은 프로그램을
- 28. 가장 효율적인 배열 셔플
- 29. 가장 효율적인 jQuery 선택기
- 30. 가장 효율적인 방법은
Monitor.Enter보다 Monitor.TryEnter의 장점은 무엇입니까? – GWLlosa
첫 번째 "Monitor.TryEnter'는 입력을 기다리는 것을 차단하지 않으며,'lock'이 사용 중이면 그 행에서 사용 가능한 상태가 될 때까지 기다리지 않고 false를 반환합니다. –