Semaphore
-
Hallo!
Ich hab da mal'n kleines problemchen. Ich will Daten in einen Puffer schreiben und wieder auslesen. Schreiben und Lesen soll jeweils in einem eigenen Thread erfolgen. Wie im Quellcode zu sehen, schreibe ich alle 500 ms einen int-Wert in den Puffer. Wie bekomm ich es mit Hilfe von Semaphoren hin, dass nur dann ein Wert ausgelesen wird, wenn auch einer im Puffer steht. Mein Problem bei vergangenen Versuchen war, dass der Lesethread ständig liest, was zu einer vollen CPU-Auslastung führt.
Hätte vielleicht jemand nen ansatz, wie man aus der Problematik rauskommt?
#include <stdio.h> #include <windows.h> #define BUFFER_SIZE 10 class CCB //Ringpufferklasse { private: int m_aiBuffer[BUFFER_SIZE]; long m_lWritePos; long m_lReadPos; public: CCB(void); ~CCB(void); void Write(int iValue); int Read(); }; class CTest //Testklasse { private: CCB &m_oCBB; public: CTest(CCB &roCCB); ~CTest(void); void Send(int iValue); }; //Ringpufferfunktionen ////////////////////////// //////////////////////////////////////////////// CCB::CCB(void) { m_lReadPos = -1; m_lWritePos = 0; for(int i=0; i<BUFFER_SIZE; i++) { m_aiBuffer[i] = 0; } } CCB::~CCB(void) { } void CCB::Write(int iValue) { m_aiBuffer[m_lWritePos] = iValue; m_lWritePos++; if(m_lWritePos >= BUFFER_SIZE) { m_lWritePos = 0; } } int CCB::Read() { m_lReadPos++; if(m_lReadPos >= BUFFER_SIZE) { m_lReadPos = 0; } return m_aiBuffer[m_lReadPos]; } //Testklassenzeugs///////////////////// CTest::CTest(CCB &roCCB) : m_oCBB(roCCB) { } CTest::~CTest(void) { } void CTest::Send(int iValue) { m_oCBB.Write(iValue); Sleep(500); } //Threadfunktionen/////////////// ///////////////////////////////// DWORD WINAPI WriteThread(LPVOID); DWORD WINAPI ReadThread(LPVOID); HANDLE g_hWriteThread, g_hReadThread, g_hSemaphore; DWORD g_dwWriteThreadID, g_dwReadThreadID; CCB *g_oCCB = new CCB(); CTest *g_oTest = new CTest(*g_oCCB); bool g_bIsBufferFilled = false; //MAIN////////////////////// //////////////////////////// void main() { g_hSemaphore = CreateSemaphore(NULL, 0, BUFFER_SIZE, NULL); g_hWriteThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WriteThread, NULL, 0, &g_dwWriteThreadID); g_hReadThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReadThread, NULL, 0, &g_dwReadThreadID); } DWORD WINAPI WriteThread(LPVOID lp) { for(int i=0; i<50; i++) { g_oTest->Send(i); g_bIsBufferFilled = true; ReleaseSemaphore(g_hSemaphore, 1, NULL); } g_bIsBufferFilled = false; return TRUE; } DWORD WINAPI ReadThread(LPVOID lp) { while(g_bIsBufferFilled == true) { if(WaitForSingleObject(g_hSemaphore, 0) == WAIT_OBJECT_0) { printf("%d\n", g_oCCB->Read()); } } return TRUE; }
-
1. Du bist im WinAPI Forum besser aufgehoben.
2. Würde ich hier nicht mal eine Semaphore, sondern nur ein Event (CreateEvent(..), SetEvent(..), ResetEvent(..), WaitForSingleObject(..)) benutzen.Simon
-
na ok, danke für den tipp...
-
Dieser Thread wurde von Moderator/in evilissimo aus dem Forum C++ in das Forum WinAPI verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Hallo SuperAdmin,
schau Dir mal diesen Beitrag zum Active Object an. Du findest dort alle Komponenten die Du benötigst wieder. Der schreibenden Thread ist main, der lesende ist in der Methode Actor::run(). Dein int ist dort die struct Cmd, und der Buffer (bzw. die Pipe oder Queue) ist der Member Actor::m_input. Die Funktionalität des Semaphore wird mit Hilfe einer boost::condition erledigt.
Gruß
Werner
-
warum soll er denn jetzt boost benutzen. die winapi hat jawohl mehr als genug bordmittel für synchronisation. @op: was funzt an deinem code nicht.