Threads synchronisieren(criticalSection)
-
Hallo,
vorweg:
Kann mir gut vorstellen, dass sowas schon x-mal da war, aber die
Suche nach "thread" liefert genau einen Treffer, und der ist unbrauchbar.Über Google hab ich noch das hier gefunden:
http://www.c-plusplus.net/forum/viewtopic-var-p-is-284835.html
aber leider funktioniert's nicht so, wie ich's mir vorstelle:Vorkenntnisse über Threads: NULL
kleines Testprogramm:
#include <iostream> #include <windows.h> using namespace std; class cSection { public: cSection() { InitializeCriticalSection(&m_criticalSection); EnterCriticalSection(&m_criticalSection); } ~cSection() {LeaveCriticalSection(&m_criticalSection);} private: CRITICAL_SECTION m_criticalSection; }; ////////////////////////////////////////////// DWORD WINAPI ThreadProc(LPVOID lpParameter); ////////////////////////////////////////////// int main() { HANDLE hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL); for (int i = 0; i < 10; i++) { cSection cs; cout<<"in main(): "<<i<<endl; cout.flush(); Sleep(500); } WaitForSingleObject(hThread, INFINITE); return 0; } ////////////////////////////////////////////// DWORD WINAPI ThreadProc(LPVOID lpParameter) { for (int i = 0; i < 10; i++) { cSection cs; cout<<"im Thread: "<<i<<endl; cout.flush(); Sleep(1000); } return 0; }Warum wird die Ausgabe vermischt?
Hab ich den Sinn von CriticalSection falsch verstanden?in main(): 0 im Thread: 0 in main(): 1 imin main(): 2 Thread: 1 in main(): 3 im Thrinead: 2 main(): 4 in main(): 5 im Thread:in main(): 3 6 in main(): 7 im Thread: 4 in main(): 8 in main(): 9 im Thread: 5 im Thread: 6 im Thread: 7 im Thread: 8 im Thread: 9thx
Martin
-
Es sollte nur einmal in deinem Programm InitializeCriticalSection aufgerufen werden.
-
int main() { HANDLE hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL); for (int i = 0; i < 10; i++) { cSection cs;DWORD WINAPI ThreadProc(LPVOID lpParameter) { for (int i = 0; i < 10; i++) { cSection cs;Dein problem :
main::cs hat nix zu tun mit ThreadProc::cs du lockst also 2 mal 2 voellig unterschiedliche sectionen ...LockObjecte, also das was du versuchst mit deiner cSection klasse zu bauen, also Objecte die beim automatischen destruieren das Object wieder freigeben, werden meist so gebaut, das sie nen Object zum Locken im Construktor bekommmen !
Besser also waere sowas:
class SimpleCriticalSection { public: SimpleCriticalSection() { ::InitializeCriticalSection(&m_cs); } ~SimpleCriticalSection() { ::DeleteCriticalSection(&m_cs); } void Lock() { ::EnterCriticalSection(&m_cs); } void Unlock() { ::LeaveCriticalSection(&m_cs); } private: CRITICAL_SECTION m_cs; }; template<class CriticalSectionT = SimpleCriticalSection> class LockObject { public: LockObject(CriticalSectionT & rxcs): mrxcs(rxcs) { mrxcs.Lock(); } ~LockObject() { mrxcs.Unlock(); } private: CriticalSectionT & mrxcs; };Angewendet:
int main() { SimpleCriticalSection mcs; HANDLE hThread = CreateThread(NULL, 0, ThreadProc, &mcs, 0, NULL); // CS als parameter uebergeben ! for (int i = 0; i < 10; i++) { LockObject<SimpleCriticalSection> LockObj(mcs); cout<<"in main(): "<<i<<endl; cout.flush(); Sleep(500); } WaitForSingleObject(hThread, INFINITE); return 0; } DWORD WINAPI ThreadProc(LPVOID lpParameter) { SimpleCriticalSection * pcs = reinterpret_cast<SimpleCriticalSection *>(lpParameter); for (int i = 0; i < 10; i++) { LockObject<SimpleCriticalSection> LockObj(* pcs); cout<<"im Thread: "<<i<<endl; cout.flush(); Sleep(1000); } return 0; }Sind bestimmt noch viele fehler drinnen, aber Prinzip sollte ok sein !

Ciao ...
-
Danke schön,
jetzt läuft's wunderbar *freu*