3 스트림을 관리하는 buffermanager를 작성하려고합니다. 전형적인 사용법은 느린 생산자 및 빠른 소비자 일 것입니다. 세 가지 버퍼 뒤에있는 아이디어는 항상 제작자가 쓸 버퍼가 있으며 소비자는 항상 최신 데이터를 가져온다는 것입니다.생산자/소비자, 스트림 버퍼 문제
이제 저는 이미 이것을 가지고 있으며, 그것은 잘 작동합니다. 버퍼는 여전히 데이터를 기록해야하므로 writebuffer가 요구되고 처음으로, 그 소비자 펄스 수 없기
namespace YariIfStream
{
/// <summary>
/// A class that manages three buffers used for IF data streams
/// </summary>
public class YariIFStream
{
private Stream writebuf; ///<value>The stream used for writing</value>
private Stream readbuf; ///<value>The stream used for reading</value>
private Stream swapbuf; ///<value>The stream used for swapping</value>
private bool firsttime; ///<value>Boolean used for checking if it is the first time a writebuffers is asked</value>
private Object sync; ///<value>Object used for syncing</value>
/// <summary>
/// Initializes a new instance of the Yari.YariIFStream class with expandable buffers
/// </summary>
public YariIFStream()
{
sync = new Object();
eerste = true;
writebuf = new MemoryStream();
readbuf = new MemoryStream();
swapbuf = new MemoryStream();
}
/// <summary>
/// Returns the stream with the buffer with new data ready to be read
/// </summary>
/// <returns>Stream</returns>
public Stream GetReadBuffer()
{
lock (sync)
{
Monitor.Wait(sync);
Stream tempbuf = swapbuf;
swapbuf = readbuf;
readbuf = tempbuf;
}
return readbuf;
}
/// <summary>
/// Returns the stream with the buffer ready to be written with data
/// </summary>
/// <returns>Stream</returns>
public Stream GetWriteBuffer()
{
lock (sync)
{
Stream tempbuf = swapbuf;
swapbuf = writebuf;
writebuf = tempbuf;
if (!firsttime)
{
Monitor.Pulse(sync);
}
else
{
firsttime = false;
}
}
//Thread.Sleep(1);
return writebuf;
}
}
}
firsttime 검사가 사용된다. writebuffer가 두 번째로 요청되면 이전 버퍼에 데이터가 포함되어 있는지 확인할 수 있습니다.
두 스레드, 한 프로듀서와 한 소비자가 있습니다. 이 내 출력 :
prod: uv_hjd`alv cons: N/<]g[)8fV
prod: N/<]g[)8fV cons: 5Ud*tJ-Qkv
prod: 5Ud*tJ-Qkv cons: 4Lx&Z7qqjA
prod: 4Lx&Z7qqjA cons: kjUuVyCa.B
prod: kjUuVyCa.B
가 지금은 소비자가 뒤에 하나를 지연 괜찮아, 그렇게 할 예정이다. 당신이 볼 수 있듯이 내 첫 번째 문자열을 잃어 버리는 것이 나의 주된 문제이다. 내가 firsttime 체크를 제거하면
- , 그것은 작동합니다
다른 문제점이있다. 하지만 그건 내 의견으로해서는 안된다 ...
- 만약 내가 Thread.Sleep (1); GetWriteBuffer()에서도 작동합니다. 뭔가 이해가 안되네.
계몽에 대해 미리 감사드립니다.
왜 4 버퍼입니까? 스왑하려면 읽기 버퍼, 쓰기 버퍼 및 임시 버퍼 만 있으면됩니다. –
펄스와 대기 사이에 동기화가 없습니다. Monitor 클래스는 Pulse 메서드가 호출되었음을 나타내는 상태를 유지 관리하지 않습니다. 따라서 대기중인 스레드가 없을 때 Pulse를 호출하면 Pulse가 호출 된 적이없는 것처럼 대기 블록을 호출하는 다음 스레드가 차단됩니다. –