Thread Synchronisation
-
guten abend
Hepi schrieb:
Wenn Du bereit bist, etwas Geld zu investieren, kann ich Dir nur den Richter ans Herz legen. Da wird das bis zum Abwinken durchgekaut...
das wollte ich mir schon kaufen, doch 100€ bei amazon ist mir doch etwas zu viel
das würde mein budget nicht mitmachen, vielleicht sollte ich mal meinen chef fragen, der könnte es finanzieren
CMatt schrieb:
was ist denn in deinen augen ne korrekte ausgabe?
folgendes:
die ausgabe heisst "ich bin 1" oder "ich bin 0"
es kommt vor das zb "iiiiccch bbbiiin 1111" ausgegeben wird. das ist schlicht weg falsch. die ausgabe mag zwar richtig sprich die threads geben immer "ich bin 1" oder "ich bin 0" aus. doch am ende kommt manchmal eben so eine mischung raus
das habe ich mit falscher ausgabe definiertgruß xerxes
-
cout ist nicht threadfest. na, und?
einfach ne critsect drum und gut.
siehe EnterCriticalSection in deiner lieblings-online-hilfe.bau ne globale critsect namens coutCritsect und mach immer vor cout<<bla ein entern und danach ein leaven.
-
#include <iostream> #include <windows.h> #include <stdio.h> #include <winbase.h> //#pragma comment(lib, "coremain.lib") #define MAX_THREADS 10 using namespace std; DWORD WINAPI ThreadFunc(LPVOID data); int main() { HANDLE hThread[MAX_THREADS]; // Handles auf die Threads DWORD dwThreadID[MAX_THREADS]; // IDs der Threads int ThreadPara = 2; int a = 1; int *p = &a; for(int i = 0; i < MAX_THREADS; i++) hThread[i] = CreateThread(NULL, 0, ThreadFunc, (LPVOID)p, 0, &dwThreadID[i]); cout << "Threads gestartet..." << endl; while(true) { *p != 0 ? *p = 0 : *p = 1; Sleep(2000); } for (i = 0; i < MAX_THREADS; i++) CloseHandle(hThread[i]); return 0; } DWORD WINAPI ThreadFunc(LPVOID data) { CRITICAL_SECTION csMyCriticalSection; int *p = (int*) data; while(1) { if(*p != 0) { EnterCriticalSection (&csMyCriticalSection); cout << "ich bin 1" << endl; LeaveCriticalSection (&csMyCriticalSection); Sleep(1000); } else { EnterCriticalSection (&csMyCriticalSection); cout << "ich bin 0" << endl; LeaveCriticalSection (&csMyCriticalSection); Sleep(1000); } } DeleteCriticalSection(&csMyCriticalSection); return ((DWORD) data); }nach dem ausführen wird nur "Threads gestartet..." ausgeben und dann erscheint nichts mehr. hab ich den kritischen abschnitt richtig angewandt?
gruß xerxes
-
#include <iostream> #include <windows.h> #include <stdio.h> #include <winbase.h> //#pragma comment(lib, "coremain.lib") #define MAX_THREADS 10 using namespace std; DWORD WINAPI ThreadFunc(LPVOID data); void EnterSection(void); void LeaveSection(void); // mutex: false entspricht Section ist frei // mutex: true entspricht Section ist vergeben bool Mutex = false; int main() { HANDLE hThread[MAX_THREADS]; // Handles auf die Threads DWORD dwThreadID[MAX_THREADS]; // IDs der Threads int ThreadPara = 2; int a = 1; int *p = &a; for(int i = 0; i < MAX_THREADS; i++) hThread[i] = CreateThread(NULL, 0, ThreadFunc, (LPVOID)p, 0, &dwThreadID[i]); cout << "Threads gestartet..." << endl; while(true) { *p != 0 ? *p = 0 : *p = 1; Sleep(200); } for (i = 0; i < MAX_THREADS; i++) CloseHandle(hThread[i]); return 0; } DWORD WINAPI ThreadFunc(LPVOID data) { int *p = (int*) data; while(1) { if(*p != 0) { EnterSection(); cout << "ich bin 1" << endl; Sleep(100); LeaveSection(); } else { EnterSection(); cout << "ich bin 0" << endl; Sleep(100); LeaveSection(); } } return ((DWORD) data); } void EnterSection(void) { while(1) { if(!Mutex) { Mutex = true; break; } Sleep(10); } } void LeaveSection(void) { Mutex = false; }ausgabe: es wird im abstand von 200 milisekunden immer "ich bin 1" oder "ich bin
0" ausgegeben. ich würde nur gerne wissen welcher thread gerade schreibt. ich hab die vermutung das nicht alle threads die erlaubnis bekommen zu schreiben.
gruß xerxesedit: hier ein screenshot zur programmlaufzeit screenshot
-
nach dem ausführen wird nur "Threads gestartet..." ausgeben und dann erscheint nichts mehr. hab ich den kritischen abschnitt richtig angewandt?
gruß xerxes
Nein hast Du nicht (hast die CriticalSection nicht initialisiert, außerdem sollte sie global sein damit alle Threads drauf zugreifen können...
#include <iostream> #include <windows.h> #include <stdio.h> #include <winbase.h> //#pragma comment(lib, "coremain.lib") #define MAX_THREADS 10 using namespace std; DWORD WINAPI ThreadFunc(LPVOID data); CRITICAL_SECTION csMyCriticalSection; int main() { HANDLE hThread[MAX_THREADS]; // Handles auf die Threads DWORD dwThreadID[MAX_THREADS]; // IDs der Threads InitializeCriticalSection(&csMyCriticalSection); int ThreadPara = 2; int a = 1; int *p = &a; for(int i = 0; i < MAX_THREADS; i++) hThread[i] = CreateThread(NULL, 0, ThreadFunc, (LPVOID)p, 0, &dwThreadID[i]); cout << "Threads gestartet..." << endl; while(true) { *p != 0 ? *p = 0 : *p = 1; Sleep(2000); } for (i = 0; i < MAX_THREADS; i++) CloseHandle(hThread[i]); DeleteCriticalSection(&csMyCriticalSection); return 0; } DWORD WINAPI ThreadFunc(LPVOID data) { int *p = (int*) data; while(1) { if(*p != 0) { EnterCriticalSection (&csMyCriticalSection); cout << "ich bin 1" << endl; LeaveCriticalSection (&csMyCriticalSection); Sleep(1000); } else { EnterCriticalSection (&csMyCriticalSection); cout << "ich bin 0" << endl; LeaveCriticalSection (&csMyCriticalSection); Sleep(1000); } } DeleteCriticalSection(&csMyCriticalSection); return ((DWORD) data); }
-
hi,
nach der initialisierung funktionierts
hier hab ich noch einen code. was mich beim folgenden code verwirrt, ist, dass stets die reihenfolge der zahlenreiche eingehalten wird.#include <iostream> #include <windows.h> #include <stdio.h> #include <winbase.h> //#pragma comment(lib, "coremain.lib") #define MAX_THREADS 10 using namespace std; DWORD WINAPI ThreadFunc(LPVOID data); void EnterCoutSection(void); void LeaveCoutSection(void); // Thread_Die sagt ob alle Threads sterben sollen odernicht bool Thread_Die = false; bool CoutMutex = false; int main() { HANDLE hThread[MAX_THREADS]; // Handles auf die Threads DWORD dwThreadID[MAX_THREADS]; // IDs der Threads int ThreadPara = 2; int a = 1; int *p_a = &a; for(int i = 0; i < MAX_THREADS; i++) hThread[i] = CreateThread(NULL, 0, ThreadFunc, (LPVOID)p_a, 0, &dwThreadID[i]); cout << "Threads gestartet..." << endl; for(i = 1; i < 201; i++) { *p_a = i; Sleep(100); } Thread_Die = true; /* WaitForMultipleObjects( MAX_THREADS, hThread, TRUE, INFINITE); Thread_Die = true;*/ for (i = 0; i < MAX_THREADS; i++) CloseHandle(hThread[i]); cout << endl; return 0; } DWORD WINAPI ThreadFunc(LPVOID data) { int *p = (int*) data; while(!Thread_Die) { if(*p != 0) { EnterCoutSection(); Sleep(100); cout << *p << endl; LeaveCoutSection(); } else break; Sleep(100); } return ((DWORD) data); } void EnterCoutSection(void) { while(true) { if(!CoutMutex) { CoutMutex = true; break; } Sleep(100); } } void LeaveCoutSection(void) { CoutMutex = false; }
-
xerxes schrieb:
was mich beim folgenden code verwirrt, ist, dass stets die reihenfolge der zahlenreiche eingehalten wird.
Was wundert dich daran? Es greifen doch alle Threads auf dieselbe Adresse zu

-
hi
ich hier einen source code der manchen der obigen anforderungen des programms entspricht.
nur macht die falsche synchronisation laufzeitfehler.
bzw ips werden doppelt, dreifach oder mehrfach aufgelöst.
ich müsste dieses programm so modifizieren, dass jede ip nur einmal aufgelöst wird und die reihenfolge von 0 - 255 eingehalten wird.#include <iostream> #include <windows.h> #include <stdio.h> #include <winbase.h> #include <sstream> //#pragma comment(lib, "coremain.lib") #pragma comment(lib, "ws2_32.lib") #define MAX_THREADS 10 using namespace std; DWORD WINAPI ThreadFunc(LPVOID data); void EnterCoutSection(void); void LeaveCoutSection(void); string convert_int(int convert); // Thread_Die sagt ob alle Threads sterben sollen odernicht bool Thread_Die = false; bool CoutMutex = false; int main() { HANDLE hThread[MAX_THREADS]; // Handles auf die Threads DWORD dwThreadID[MAX_THREADS]; // IDs der Threads int ThreadPara = 2; string ip; string *p_ip = &ip; WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD( 2, 2); WSAStartup( wVersionRequested, &wsaData ); for(int i = 0; i < MAX_THREADS; i++) hThread[i] = CreateThread(NULL, 0, ThreadFunc, (LPVOID)p_ip, 0, &dwThreadID[i]); cout << "Threads gestartet..." << endl; for(i = 0; i < 256; i++) { string temp; temp = convert_int(i); *p_ip = "213.147.0." + temp; Sleep(100); } Thread_Die = true; /* WaitForMultipleObjects( MAX_THREADS, hThread, TRUE, INFINITE); Thread_Die = true;*/ for (i = 0; i < MAX_THREADS; i++) CloseHandle(hThread[i]); cout << endl; return 0; } DWORD WINAPI ThreadFunc(LPVOID data) { string *p = (string*) data; HOSTENT *host; in_addr inet; while(!Thread_Die) { inet.S_un.S_addr = inet_addr(p->c_str()); host = gethostbyaddr((const char*) &inet, 4, AF_INET); EnterCoutSection(); cout << *p << " = " << host->h_name << endl; LeaveCoutSection(); Sleep(10); } return ((DWORD) data); } void EnterCoutSection(void) { while(true) { if(!CoutMutex) { CoutMutex = true; break; } Sleep(5); } } void LeaveCoutSection(void) { CoutMutex = false; } string convert_int(int convert_int) { stringstream str; string foo; str << convert_int; str >> foo; return foo; }
-
Dann müsstest du in den Threads (nicht im Haupt-Thread) die IP hochzählen, nachdem du sie aufgelöst hast

Du solltest dann aber wenn mehrere Threads aber das ändern der IP und das rauskopieren noch in die CriticalSection packen
-
_xerxes schrieb:
void EnterCoutSection(void) { while(true) { if(!CoutMutex) { CoutMutex = true; break; } Sleep(5); } } void LeaveCoutSection(void) { CoutMutex = false; }Lass dir sowas bloß nicht aufschwätzen! Wenn dein Thread genau zwischen if(!CoutMutex) und CoutMutex=true unterbrochen wird, und zufällig gerade ein anderer Thread ebenfalls CoutMutex sperren will, dann hast du zwei Threads gleichzeitig in dem geschützten Bereich herumschreiben. Wenn du unbedingt etwas Hausgemachtes willst, also keine CRITICAL_SECTION verwenden willst, dann bitte etwas in dieser Art:
LONG CritSect = FALSE; void EnterCoutSection() { while(InterlockedExchange(&CritSect, TRUE) != FALSE) Sleep(0); } void LeaveCoutSection() { InterlockedExchange(&CritSect, FALSE); }