성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] VT sequences to "CONOUT$" vs. STD_O...
[정성태] NetCoreDbg is a managed code debugg...
[정성태] Evaluating tail call elimination in...
[정성태] What’s new in System.Text.Json in ....
[정성태] What's new in .NET 9: Cryptography ...
[정성태] 아... 제시해 주신 "https://akrzemi1.wordp...
[정성태] 다시 질문을 정리할 필요가 있을 것 같습니다. 제가 본문에...
[이승준] 완전히 잘못 짚었습니다. 댓글 지우고 싶네요. 검색을 해보...
[정성태] 우선 답글 감사합니다. ^^ 그런데, 사실 저 예제는 (g...
[이승준] 수정이 안되어서... byteArray는 BYTE* 타입입니다...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>.NET에서 Producer/Consumer를 구현한 BlockingCollection<T></h1> <p> 지난 글에서,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > .NET에서 Producer/Consumer를 구현하는 기초 인터페이스 - IProducerConsumerCollection<T> ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/12993'>https://www.sysnet.pe.kr/2/0/12993</a> </pre> <br /> IProducerConsumerCollection<T> 인터페이스를 다뤘는데요, 사실 저 인터페이스만 구현해서는 현실적으로 Producer/Consumer 모델에 사용하기가 좀 번거롭습니다. 가령, 데이터를 생성하는 측면에서 보면 단순히 Concurrent 컬렉션에 값을 넣기만 하면 되므로 그다지 문제가 안 되지만, 데이터를 소비하는 측면에서 보면 언제 데이터가 올지 알 수 없으므로 폴링 방식으로 데이터를 계속 체크하든가, 아니면 signal을 이용해 데이터의 유무를 확인하는 부가 코드를 넣어야 합니다.<br /> <br /> 바로 그러한 부가 작업을 담당하도록 마이크로소프트가 미리 제공하는 클래스가 <a target='tab' href='https://learn.microsoft.com/en-us/dotnet/api/system.collections.concurrent.blockingcollection-1'>BlockingCollection<T></a>입니다. 사실 이전 글에서 IProducerConsumerCollection을 IConcurrentCollection의 의미로 봐야 한다고 했는데요, 그렇게 따졌을 때 사실상 BlockingCollection이야말로 IProducerConsumerCollection 인터페이스라는 이름을 상속받는 것이 더 어울릴 것입니다.<br /> <br /> 간단하게 필요한 부분만 내부 구현 방식을 살펴볼까요?<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > BlockingCollection.cs ; <a target='tab' href='https://referencesource.microsoft.com/#system/sys/system/collections/concurrent/BlockingCollection.cs'>https://referencesource.microsoft.com/#system/sys/system/collections/concurrent/BlockingCollection.cs</a> </pre> <br /> BlockingCollection<T>는 이미 thread-safe하게 구현한, 즉 IProducerConsumerCollection<T> 인터페이스를 구현한 타입의 내부 필드를 선언해 두고 관련한 작업들은 그것에 맡깁니다. 단지, 추가된 것이라면 <a target='tab' href='https://www.sysnet.pe.kr/2/0/13156#semaphore_slim'>SemaphoreSlim</a>을 이용해 해당 자료 구조에서 값을 넣고 빼는 것에 대한 blocking 기능을 제공하는 정도입니다. 즉, <a target='tab' href='https://www.sysnet.pe.kr/2/0/1015#4'>스레드 대기 기능만 추가된 것</a>입니다.<br /> <br /> 사용자가 명시하지 않은 경우, 기본적으로 BlockingCollection<T>는 (<a target='tab' href='https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.queue-1'>Queue<T></a>의 thread-safe 버전인) <a target='tab' href='https://learn.microsoft.com/en-us/dotnet/api/system.collections.concurrent.concurrentqueue-1'>ConcurrentQueue<T></a>를 사용하기 때문에 FIFO 구조의 Producer/Consumer 동작을 하게 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > public class BlockingCollection<T> : IEnumerable<T>, ICollection, IDisposable, IReadOnlyCollection<T> { public BlockingCollection() : this(<span style='color: blue; font-weight: bold'>new ConcurrentQueue<T>()</span>) { } // ...[생략]... } </pre> <br /> 물론, BlockingCollection<T> 생성자에 ConcurrentStack<T>을 전달한다면 FILO 방식으로 동작합니다.<br /> <br /> 좀 더 자세한 내용은 아래의 글을 확인하시고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > BlockingCollection Overview ; <a target='tab' href='https://learn.microsoft.com/en-us/dotnet/standard/collections/thread-safe/blockingcollection-overview'>https://learn.microsoft.com/en-us/dotnet/standard/collections/thread-safe/blockingcollection-overview</a> BlockingCollection 컬렉션 소개 ; <a target='tab' href='https://forum.dotnetdev.kr/t/blockingcollection/512'>https://forum.dotnetdev.kr/t/blockingcollection/512</a> </pre> <br /> 참고로, 예전에 저는 화면 캡처한 것을 Queue에 넣고, 다른 스레드에서 그것을 받아 처리하는 용도로 BlockingCollection을 사용한 적이 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C# - OpenCvSharp을 이용한 Webcam 영상 처리 + Direct2D ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/11405'>https://www.sysnet.pe.kr/2/0/11405</a> // 기타 사용 예제 SingleThreadTaskScheduler에서 사용한 예제 ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/13188#SingleThreadTaskScheduler'>https://www.sysnet.pe.kr/2/0/13188#SingleThreadTaskScheduler</a> </pre> <br /> 그리고, Win32 메시지도 처리한다는데,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 72. Thread.Yield나 Thread.Join은 COM 메시지를 처리할까? ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/11879#72'>https://www.sysnet.pe.kr/2/0/11879#72</a> </pre> <br /> 이것은 BlockingCollection이 사용하는 SemaphoreSlim이 결국 Monitor.Enter 등을 사용하기 때문으로 얻어지는 효과로 보입니다.<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
9545
(왼쪽의 숫자를 입력해야 합니다.)