Kann man einem Thread eine CPU zuordnen??? Bsp. Primberechnung
-
Hallo volkard,
Danke sehr für die rasche Antwort.
Stimmt das leuchtet ziehmlich ein. Was du da vorschlägst fordert natürlich
eine ganz neue Struktur meines Programms.
Abgesehen davon habe ich noch keine Ahnung, wie ich die Geschichte mit den Threads händeln werde.
Jedoch scheint mir dein Vorschlag sehr viel effektiver zu sein, als mein Ansatz.
Also werde ich, dem jeweils wartenden CPU-Kern die nächste Zahl zum berechnen geben? So habe ich dies verstanden. Dafür muss man ja ermitteln welcher Kern gerade frei ist, hmmhmmmmm "nächste Frage"?Für die, die es interessiert. Hier ist mein SingleCoreCode....nicht anspruchsvoll
aber leicht erweiterbar.// PrimSingleCore.cpp : Definiert den Einsprungpunkt für die Anwendung. // #include "stdafx.h" #include <windows.h> #include <stdlib.h> #include <math.h> LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); HINSTANCE hInstGlobal; HWND hWindow, hButtonStart, hButtonStop, hButtonExit; HDC hdc; static RECT rect, rect1; SYSTEMTIME systime,systimeold; //time-variable int hDiff = 0; int mDiff = 0; int sDiff = 0; int msDiff = 0; CONST aim = 500000; //Zielzahl int count; //Anzahl char *Gstring; //globaler String bool th1runs; bool flag1; const UINT TimerSec = 1; //TIMER int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { hInstGlobal = hInstance; WNDCLASS WndClass; WndClass.style = 0; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.lpfnWndProc = WndProc; WndClass.hInstance = hInstance; WndClass.hbrBackground = (HBRUSH) (COLOR_WINDOW+11); WndClass.hCursor = LoadCursor (NULL, IDC_ARROW); WndClass.hIcon = LoadIcon (NULL, IDI_APPLICATION); WndClass.lpszMenuName = 0; WndClass.lpszClassName = "WinProg"; RegisterClass(&WndClass); Gstring = new char[20]; SetTimer(hWindow, TimerSec, 14, NULL); //TIMER hWindow = CreateWindow("WinProg","PrimDualCore", WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX, 0,0,800,600,NULL,NULL, hInstance, NULL); ShowWindow (hWindow, nCmdShow); UpdateWindow (hWindow); MSG Message; while (GetMessage(&Message, NULL, 0, 0)) { DispatchMessage(&Message); } return (Message.wParam); } void calcDiff() //Zeitschieber-Methode { hDiff = systime.wHour-systimeold.wHour; mDiff = systime.wMinute-systimeold.wMinute; sDiff = systime.wSecond-systimeold.wSecond; msDiff= systime.wMilliseconds-systimeold.wMilliseconds; if(msDiff<0){sDiff--; msDiff=msDiff+1000;} if(sDiff<0){mDiff--; sDiff=sDiff+60;} if(mDiff<0){hDiff--; mDiff=mDiff+60;} if(hDiff<0){hDiff=hDiff+24;} } bool Prim(int zahl) { bool devided = false; // erg = sqrt(aim); for(int k=3;k<(sqrt(zahl)+1);k=k+2) { if((zahl%k) == 0){ devided=true; k=zahl;} } return !devided; } DWORD WINAPI ThreadProc1( LPVOID pvoid ) { flag1 = false; InvalidateRect(hWindow, &rect1, TRUE); TEXTMETRIC tm; GetTextMetrics (hdc, &tm); int i; //Laufvariable int ix,iy; count=1; //wegen der 2 ix = 0; iy = 0; char *string; string = new char[20]; { // einmalige Ausgabe der 2 da diese nicht im DB von Prim(2) ist hdc = GetDC (hWindow); SetBkColor (hdc, RGB(236,233,216)); wsprintf(string,"%01d",2); TextOut (hdc, ix, iy, string, lstrlen(string)); iy = iy + tm.tmHeight; ReleaseDC (hWindow, hdc); } for (i=3;i<=aim;i=i+2) { if(Prim(i)) { count++; hdc = GetDC (hWindow); wsprintf(string,"%01d",i); SetBkColor (hdc, RGB(236,233,216)); TextOut (hdc, ix, iy, string, lstrlen(string)); iy = iy + tm.tmHeight; if ((iy/tm.tmHeight) == 33) { iy = 0; ix = ix + 90; } if(ix>770) { ix=0; iy=0;} ReleaseDC (hWindow, hdc); } } flag1 = true; GetSystemTime(&systime); //take time END calcDiff(); InvalidateRect(hWindow, &rect1, TRUE); delete [] string; th1runs = false; return NULL; } LRESULT CALLBACK WndProc (HWND hWnd, UINT uiMessage, WPARAM wParam,LPARAM lParam) { static HANDLE hThread1; switch(uiMessage) { case WM_SIZE: { rect.left = 0; //x-links TEST rect.top = 0; //y-oben TEST rect.right = 800; //x-rechts TEST rect.bottom = 600; //y-unten TEST rect1.left = 360; //x-links TEST rect1.top = 530; //y-oben TEST rect1.right = 800; //x-rechts TEST rect1.bottom = 600; //y-unten TEST return 0; } case WM_CREATE: hButtonStart = CreateWindow ("BUTTON","START", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 10,540,100,20, hWnd,(HMENU) 1, hInstGlobal, NULL); hButtonStop = CreateWindow ("BUTTON","STOP", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 120,540,100,20, hWnd,(HMENU) 2, hInstGlobal, NULL); hButtonExit = CreateWindow("BUTTON","Exit", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 250,540,80,20, hWnd,(HMENU) 3, hInstGlobal, NULL); return 0; case WM_TIMER: { //InvalidateRect(hWnd, &rect1, TRUE); // bewirkt die Aktuallisierung im Bereich von rect1 //TIMER return 0; } case WM_PAINT: { HDC hdc; PAINTSTRUCT ps; char *WMstring; WMstring = new char[1]; WMstring[0] = 169; // das (C)reated hdc = BeginPaint (hWnd, &ps); //BEGIN PAINT SetBkColor (hdc, RGB(236,233,216)); SetTextColor (hdc, RGB(180,0,0)); TextOut (hdc, 360, 540, "time: ", lstrlen("time: ")); if(flag1) { wsprintf( Gstring , "%02d:%02d:%02d:%03d",hDiff,mDiff,sDiff,msDiff); TextOut (hdc, 400, 540, Gstring, lstrlen(Gstring)); } SetTextColor (hdc, RGB(0,180,0)); TextOut (hdc, 540, 540, "count: ", lstrlen("count: ")); if(flag1) { wsprintf( Gstring , "%01d",count); TextOut (hdc, 590, 540, Gstring, lstrlen(Gstring)); } SetTextColor (hdc, RGB(187,187,187)); SetBkColor (hdc, RGB(236,233,216)); //Rot=236 Grün=233 Blau=216 (standart Hellgrau) TextOut (hdc, 520+184,540, WMstring, 1); TextOut (hdc, 520+200,540, "by rom4o", 8); EndPaint (hWnd, &ps); //END PAINT delete WMstring; return 0; } case WM_COMMAND: if (HIWORD(wParam) == BN_CLICKED) { if ( (LOWORD(wParam) == 1) && (th1runs == false) ) { hdc = GetDC (GetParent((HWND) lParam)); InvalidateRect(hWnd, &rect, TRUE); DWORD dwThreadParam1 = 1; DWORD dwThreadID1; th1runs = true; GetSystemTime(&systimeold); //take time BEGIN hThread1 = CreateThread (NULL, 0, ThreadProc1, &dwThreadParam1, 0, &dwThreadID1); } if (LOWORD(wParam) == 2) { TerminateThread (hThread1, 0); th1runs = false; } if (LOWORD(wParam) == 3) { SendMessage (GetParent((HWND)lParam), WM_DESTROY ,0 ,0); } } return 0; case WM_DESTROY: PostQuitMessage(0); return 0; default: return DefWindowProc (hWnd, uiMessage, wParam, lParam); }
Nun denn vielen Dank für den Tip, ich grüble weiter und gehen nun erstmal zu Bett.
grüße rom40
-
rom4o schrieb:
Also werde ich dem jeweils wartendem CPU-Kern die nächste Zahl zum berechnen geben? So habe ich dies verstanden. Dafür muss man ja ermitteln welcher Kern gerade frei ist,....haha nächste Frage.
ich denke etwa an sowas:
alle threads legen bei programmstart los.
jeder thread macht nur for(;;) { holeAufgabe(); rechne(); gibErgebnis(); }
holeAufgabe und gibErgebnis schützen sich einfach durch CreateMutex und ihre freunde.
das heißt, daß das erzeugen einer aufgabe nicht von einem bestimmten thread zu geschehen hat, sondern da arbeitet immer der, der gerade was braucht.evtl hängt zusätzlich ein anzeigethread rum, der alle userinteraktion aus einer hand zu machen hat. der kann natürlich auf die datenstrukturen von holeAufgabe und gibErgebnis auch zugreiifen. aber immer schön mit mutexen geschützt.
-
rom4o, hast du denn noch eine konkrete Frage?
-
jeder thread macht nur for(;;) { holeAufgabe(); rechne(); gibErgebnis(); }
Das ist eine sehr gute Idee und ich werde versuchen das so zu implementieren.
Jedoch habe ich erstmal ein grundlegendes Problem zu lösen.Hallo Leute ich habe nun mal in einem Programm versucht,
die Berechnung von Primzahlen auf zwei Threads aufzuteilen. So kann man dann die Threads
einzelnen CPU-Kernen zuordnen.
Mein Ziel ist ja immernoch den Prozessor komplett auszulasten.Hier der Code:
// prim_mutex_dualcore.cpp : Definiert den Einsprungpunkt für die Konsolenanwendung. // #include "stdafx.h" #include <iostream> #include <windows.h> #include <math.h> using namespace std; SYSTEMTIME systime,systimeold; //time-variable int hDiff = 0; int mDiff = 0; int sDiff = 0; int msDiff = 0; int count = 1; // 1 weil die 2 nicht berechnet wird int c=3; int aim = 1000; //int aim = 2000000; HANDLE mutex = CreateMutex( NULL, FALSE, NULL ); void calcDiff() //Zeitschieber-Methode { hDiff = systime.wHour-systimeold.wHour; mDiff = systime.wMinute-systimeold.wMinute; sDiff = systime.wSecond-systimeold.wSecond; msDiff= systime.wMilliseconds-systimeold.wMilliseconds; if(msDiff<0){sDiff--; msDiff=msDiff+1000;} if(sDiff<0){mDiff--; sDiff=sDiff+60;} if(mDiff<0){hDiff--; mDiff=mDiff+60;} if(hDiff<0){hDiff=hDiff+24;} } bool Prim(int zahl) { bool devided = false; for(int k=3;k<(sqrt(zahl)+1);k=k+2) { if((zahl%k) == 0){ devided=true; k=zahl;} } return !devided; } DWORD WINAPI ThreadProc1( LPVOID pvoid ) { while(c<=aim) { if ( WaitForSingleObject( mutex, INFINITE ) == WAIT_OBJECT_0 ) // Mutex-Zugriff holen { if(Prim(c)) { cout << "T1" << " : " << c <<endl; // Ausgabe der Primzahl count++; } c=c+2; ReleaseMutex( mutex ); // Mutex wieder freigeben } // Sleep(10); } return 0; } DWORD WINAPI ThreadProc2( LPVOID pvoid ) { while(c<=aim) { if ( WaitForSingleObject( mutex, INFINITE ) == WAIT_OBJECT_0 ) // Mutex-Zugriff holen { if(Prim(c)) { cout << "T2" << " : " << c <<endl; // Ausgabe der Primzahl count++; } c=c+2; ReleaseMutex( mutex ); // Mutex wieder freigeben } // Sleep(3000); } return 0; } void main() { // Threads erzeugen GetSystemTime(&systimeold); //take time BEGIN cout << "Thread1 startet..."<<endl; DWORD dwThreadParam1 = 1; HANDLE hThread1 = CreateThread (NULL,0,ThreadProc1,&dwThreadParam1,0,NULL); SetThreadAffinityMask(hThread1, 1); cout << "Thread2 startet..."<<endl; DWORD dwThreadParam2 = 2; HANDLE hThread2 = CreateThread (NULL,0,ThreadProc2,&dwThreadParam2,0,NULL); SetThreadAffinityMask(hThread2, 2); // Auf Threads warten WaitForSingleObject( hThread1, INFINITE ); WaitForSingleObject( hThread2, INFINITE ); GetSystemTime(&systime); //take time END calcDiff(); cout << "Time: " << hDiff << ":" << mDiff << ":" << sDiff << ":" << msDiff << endl; cout << "Anzahl: " << count <<endl; // Thread-Handles schließen CloseHandle( hThread1 ); CloseHandle( hThread2 ); // Mutex zerstören CloseHandle( mutex ); TerminateThread (hThread1, 0); TerminateThread (hThread2, 0); }
Nun habe ich als globale Variable "c" genommen, welches von jedem Thread um 2 inkrementiert wird.
Diese Inkrementierung ist durch ein Mutex abgesichert.
Mein Problem ist nun, dass immer nur ein Thread rechnet weil er auf den anderen wartet.Wie kann ich dieses Problem lösen?
Mir fällt gerade überhaupt nichts ein.
Wenn man die Textausgabe weglässt, ist das Programm schon sehr schnell.Ich habe eine Timetake-Funktion eingebaut, die die Rechenzeit anzeigt.
Da wäre auch noch die Frage wie man in der Konsole die Integerwerte konvertiert ausgibt?
Jetzt ist die Ausgabe so: "Time: 0:0:12:287", ich will die aber so haben "Time: 00:00:12:287".Vielen Dank für Ratschläge.
grüße rom4o
-
rom4o schrieb:
Mein Problem ist nun, dass immer nur ein Thread rechnet weil er auf den anderen wartet.
Du brauchst den Funktionsaufruf von "Prim(c)" ja nicht mit dem Mutex zu schützen. Du könntest also den Mutex holen, den Wert von "c" in einer neuen temporären Variable speichern, "c" erhöhen und den Mutex zurückgeben. Dann führst du "if (Prim(old_c))" aus, währenddessen kann sich der andere Thread schon den Mutex holen.
Das Problem dabei wäre nur, dass die Konsolen-Ausgabe durcheinander-geraten kann. Eine Lösung dafür wäre, erst alle Primzahlen in einem Container (entweder auch durch einen Mutex abgesichert oder jeder Thread hat seinen eigenen Container, die am Schluss zusammengefügt werden) zu speichern und erst nach den ganzen Berechnungen auszugeben.
-
int getNextCandidate() { WaitForSingleObject( mutex, INFINITE ); c=c+2; int r=c; ReleaseMutex( mutex ); return c; } void printPrime( int prime ) { WaitForSingleObject( mutex, INFINITE ); cout<<prime<<' '; ReleaseMutex( mutex ); } bool Prim(int zahl) { bool devided = false; for(int k=3;k<(sqrt(zahl)+1);k=k+2) { if((zahl%k) == 0){ devided=true; k=zahl;} } return !devided; } DWORD WINAPI ThreadProc( LPVOID pvoid ) { int cc=getNextCandidate(); while(cc<=aim) { if(Prim(cc)) printPrime(cc); cc=getNextCandidate(); } return 0; }
-
Nimm OpenMP, das macht das Leben viel einfacher... keine Gedanken mehr über Mutexe verlieren...
Ab VS2010 siehe auch PPL...
-
Wo steht geschrieben, dass die GDI multiCPU-Fähig geschweige den Threadsafe ist?
Den Satz vermisse ich seit über 20 Jahren.
-
@Badestrand: hab mich nach deinem Tip schnell rangemacht das umzusetzen und
dann kam auch schon die Lösung von volkmar@Jochen Kalmbach
Ja werde mich auch bald damit beschäftigen, aber ich will erstmal versuchen alles was möglich ist aus der WinApi herauszuholen.@CStern
Ähm, habe ich das behauptet?
Aber die Zuordnung der einzelnen Threads zu spezifischen Kernen, müsste doch
theoretisch den Prozessor voll auslasten?
Ich habe auch in meinen Tests die cout-Ausgabe herausgenommen.Hallo volkmar,
danke für diese elegante Lösung.
Es funktioniert. Aber es ist nichts schneller als vorher.
Wenn ich die Ausgabe rausnehme ist zwar alles viel schneller aber nur halbe Prozessorauslastung.
Ich kann mir das jetzt nicht erklären? Irgendwas muss schief laufen.Dazu habe ich noch count++; in deine print-Methode eingebaut
Code:void printPrime( int prime ) { WaitForSingleObject( mutex, INFINITE ); cout<<prime<<" "; count++; ReleaseMutex( mutex ); }
Das Problem ist, dass manchmal einige Werte doppelt berechnet werden.
Ich habe mal mehrmals bis 2000000 berechnen lassen.
count kommt auf folgende Werte: 149123,149058,149081,149066...usw.
In einem Puffer könnte man natürlich die doppelten Ergebnisse aussortieren,
aber wie kann es zu dieser Doppelberechnung bei deiner Verteilung kommen?Vielen Dank wieder für Ideen.
Grüße rom4o
-
int getNextCandidate() { WaitForSingleObject( mutex, INFINITE ); int r=c; c=c+2; ReleaseMutex( mutex ); return r; }
Ich denke, so war's gemeint.
Und ich würde unterschiedliche Mutexe für c-Beschützung und Ausgabe nehmen.
-
evtl ist noch
volatile int c=3;
nötig.
-
Hallo, ja Badestrand das war das Problem.
Hätte selber drauf kommen müssen
Danke euch beiden für die Tips.
Das Problem mit der halben Prozessorauslastung ist mir allerdings immernoch
ein Rätsel.
Ich denke es muss einen tieferen Grund dafür geben.
Theoretisch müsste das Programm nun mit 100% Auslastung laufen,
da jeder der Threads nun immer zu rechnen hat.Also viele Grüße bb
rom4o
-
rom4o schrieb:
Theoretisch müsste das Programm nun mit 100% Auslastung laufen,
da jeder der Threads nun immer zu rechnen hat.Jaja, die Theorie
Kommentier mal die Zeile mit "cout << ..." aus, leider warten die Threads sehr lange auf die Ausgabe.
edit: Auskommentieren, damit du siehst, dass die Threads immer "lange" Zeit in der Ausgabe hängen.
-
BTW: Warum einen langsamen Mutex nutzen wenn es schnelle CriticalSections gibt?
-
@Badestrand: Ich habe ja, wie ich auch schon geschrieben habe, die Ausgabe zum Test herausgenommen. Dann läuft das Programm sehr viel schneller aber trotzdem nur mit halber Auslastung.
Für aim=200000 und mit 'cout<<prime<<" ";' braucht mein Laptop ca. 8sec.
Für aim=200000 und ohne cout braucht er nur knapp 1sec.@Martin Richter: Könnte sein, dass es daran liegt. Habe in anderen Artikeln auch schon gelesen, dass Mutex´s aufwendig und zeitraubend sind.
Ich habe leider keine Ahnung wie man Critical Section umgeht.
Hast du vielleicht ein kurzes Beispiel?Vielen Dank euch.
rom4o
-
Martin Richter schrieb:
BTW: Warum einen langsamen Mutex nutzen wenn es schnelle CriticalSections gibt?
Ich vergesse die Critical Sections oft
Bleibt Mutexen eigentlich noch ein anderes Einsatzgebiet als Interprocess-Synchro?
rom4o schrieb:
Ich habe leider keine Ahnung wie man Critical Section umgeht.
http://www.google.de/search?hl=de&q=critical+section&btnG=Google-Suche&meta=
-
Hallo Leute,
so...jetzt haben wirs.
Ich habe auf folgender Seite http://www.kunsmann.de/cpp/critical_section.htm
eine sehr schöne Erkärung zur Critical Section gefunden, es ist auch
viel anderes Interessantes dort zu finden.Ich habe nun in meinem Primzahlenprogramm die Mutex´s durch CriticalSection´s ersetzt.
Das Programm läuft wie gewohnt und nun endlich wie von Martin Richter prophezeit
mit voller Prozessorauslastung. Wunderbar!!!!Endlich...
Das hat sich doch gelohnt.Hier ist das fertige Programm für die, die es interessiert:
// prim_cs_dualcore.cpp #include "stdafx.h" #include <iostream> #include <windows.h> #include <math.h> using namespace std; SYSTEMTIME systime,systimeold; //time-variable int hDiff = 0; int mDiff = 0; int sDiff = 0; int msDiff = 0; int count = 1; // 1 weil die 2 nicht berechnet wird int c=3; int timestep = 50; //int aim = 1000; int aim = 10000000; CRITICAL_SECTION csVarInAccess; // Critical Section definieren CRITICAL_SECTION csOutputInAccess; // Critical Section definieren void calcDiff() //Zeitschieber-Methode { hDiff = systime.wHour-systimeold.wHour; mDiff = systime.wMinute-systimeold.wMinute; sDiff = systime.wSecond-systimeold.wSecond; msDiff= systime.wMilliseconds-systimeold.wMilliseconds; if(msDiff<0){sDiff--; msDiff=msDiff+1000;} if(sDiff<0){mDiff--; sDiff=sDiff+60;} if(mDiff<0){hDiff--; mDiff=mDiff+60;} if(hDiff<0){hDiff=hDiff+24;} } bool Prim(int zahl) { bool devided = false; for(int k=3;k<(sqrt(zahl)+1);k=k+2) { if((zahl%k) == 0){ devided=true; k=zahl;} } return !devided; } int getNextCandidate() { EnterCriticalSection(&csVarInAccess); int r=c; c=c+2; LeaveCriticalSection(&csVarInAccess); return r; } void printPrime( int prime ) { EnterCriticalSection(&csOutputInAccess); // cout<<prime<<" "; count++; LeaveCriticalSection(&csOutputInAccess); } DWORD WINAPI ThreadProc1( LPVOID pvoid ) { int cc=getNextCandidate(); while(cc<=aim) { if(Prim(cc)) printPrime(cc); cc=getNextCandidate(); } return 0; } DWORD WINAPI ThreadProc2( LPVOID pvoid ) { int cc=getNextCandidate(); while(cc<=aim) { if(Prim(cc)) printPrime(cc); cc=getNextCandidate(); } return 0; } void main() { InitializeCriticalSection(&csVarInAccess); // Critical Section initialisieren InitializeCriticalSection(&csOutputInAccess); // Critical Section initialisieren GetSystemTime(&systimeold); //take time BEGIN cout << "Thread1 startet..."<<endl; DWORD dwThreadParam1 = 1; HANDLE hThread1 = CreateThread (NULL,0,ThreadProc1,&dwThreadParam1,0,NULL); SetThreadAffinityMask(hThread1, 1); EnterCriticalSection(&csOutputInAccess); cout << "Thread2 startet..."<<endl; LeaveCriticalSection(&csOutputInAccess); DWORD dwThreadParam2 = 2; HANDLE hThread2 = CreateThread (NULL,0,ThreadProc2,&dwThreadParam2,0,NULL); SetThreadAffinityMask(hThread2, 2); // Auf Threads warten WaitForSingleObject( hThread1, INFINITE ); WaitForSingleObject( hThread2, INFINITE ); GetSystemTime(&systime); //take time END calcDiff(); cout <<endl; cout << "Time: " << hDiff << ":" << mDiff << ":" << sDiff << ":" << msDiff << endl; cout << "Anzahl: " << count <<endl; // Thread-Handles schließen CloseHandle( hThread1 ); CloseHandle( hThread2 ); TerminateThread (hThread1, 0); TerminateThread (hThread2, 0); DeleteCriticalSection(&csVarInAccess); // Critical Section löschen DeleteCriticalSection(&csOutputInAccess); // Critical Section löschen }
Die Ausgabe der Primzahlen kann man in Zeile 63 wieder einstellen, jedoch läuft dann
das Programm viel viel langsamer.Ich denke man kann das Programm, auch ohne großen Aufwand, für mehr als 2 Kerne leicht anpassen.
Vielen Dank an Alle die mir hier so hilfreiche Ratschläge gegeben haben.Viele Grüße rom4o
-
und jetzt schmeiß bitte noch die ThreadProc2 weg. kannst beide male die 1 nehmen.
-
Badestrand schrieb:
Martin Richter schrieb:
BTW: Warum einen langsamen Mutex nutzen wenn es schnelle CriticalSections gibt?
Ich vergesse die Critical Sections oft
Bleibt Mutexen eigentlich noch ein anderes Einsatzgebiet als Interprocess-Synchro?
Ja, wenn man ein Wait mit Timeout braucht. Natürlich kann man sich auch das mit einer CRITICAL_SECTION, einem EVENT und einer Queue selbst stricken, und die selbst gestrickte Version wird immer noch schneller als eine MUTEX sein. Aber oft ist einem das einfach zu umständlich, und mit einer MUTEX geht das eben out of the box.
Und man kann MUTEXen einen Namen geben. An manchen Stellen ist das wichtig. Guck dir z.B. mal die Implementierung von Boost.Thread's "once" für Windows an. Das ist ein klassisches Beispiel für Fälle wo man sich viel Arbeit sparen kann, dadurch dass man solche "named objects" verwendet.
-
@volkard: ja hab ich gemacht, ich habe das ja auch von dir in deiner Vorlage so bekommen. Ich habe nur noch mal 2 einzelne Threads erstellt, weil ich unterschiedliche Sleep()-Werte bei meinen Tests reingeschrieben habe.
danke, bb rom4o