(Kurz gesagt: WaitForSingleObject von main() hängt sich im untenstehenden Programm auf).
Ich versuche, ein Codestück zu schreiben, das Threads verteilt und wartet, bis sie beendet sind, bevor es weitergeht. Anstatt die Threads jedes Mal neu zu erstellen, was kostspielig ist, versetze ich sie in den Ruhezustand. Der Hauptthread erstellt X Threads im Zustand CREATE_SUSPENDED.
Die Synchronisierung erfolgt über eine Semaphore mit X als MaximumCount. Der Zähler der Semaphore wird auf Null zurückgesetzt und die Threads werden abgearbeitet. Die drei Threads führen eine dumme Schleife aus und rufen ReleaseSemaphore auf, bevor sie schlafen gehen. Dann verwendet der Hauptthread WaitForSingleObject X-mal, um sicher zu sein, daß jeder Thread seine Aufgabe erledigt hat und schläft. Dann macht er eine Schleife und das Ganze noch einmal.
Von Zeit zu Zeit wird das Programm nicht beendet. Wenn ich das Programm beobachte, kann ich sehen, dass sich WaitForSingleObject aufhängt. Das bedeutet, dass die ReleaseSemaphore eines Threads nicht funktioniert hat. Es wird nichts gedruckt, also ist anscheinend nichts schiefgegangen.
Vielleicht sollten zwei Threads nicht genau zur gleichen Zeit ReleaseSemaphore aufrufen, aber das würde den Zweck von Semaphoren zunichte machen...
Ich verstehe es einfach nicht...
Andere Lösungen für Synchronisierungsfäden werden dankbar angenommen!
#define TRY 100
#define LOOP 100
HANDLE *ids;
HANDLE semaphore;
DWORD WINAPI Count(__in LPVOID lpParameter)
{
float x = 1.0f;
while(1)
{
for (int i=1 ; i<LOOP ; i++)
x = sqrt((float)i*x);
while (ReleaseSemaphore(semaphore,1,NULL) == FALSE)
printf(" ReleaseSemaphore error : %d ", GetLastError());
SuspendThread(ids[(int) lpParameter]);
}
return (DWORD)(int)x;
}
int main()
{
SYSTEM_INFO sysinfo;
GetSystemInfo( &sysinfo );
int numCPU = sysinfo.dwNumberOfProcessors;
semaphore = CreateSemaphore(NULL, numCPU, numCPU, NULL);
ids = new HANDLE[numCPU];
for (int j=0 ; j<numCPU ; j++)
ids[j] = CreateThread(NULL, 0, Count, (LPVOID)j, CREATE_SUSPENDED, NULL);
for (int j=0 ; j<TRY ; j++)
{
for (int i=0 ; i<numCPU ; i++)
{
if (WaitForSingleObject(semaphore,1) == WAIT_TIMEOUT)
printf("Timed out !!!\n");
ResumeThread(ids[i]);
}
for (int i=0 ; i<numCPU ; i++)
WaitForSingleObject(semaphore,INFINITE);
ReleaseSemaphore(semaphore,numCPU,NULL);
}
CloseHandle(semaphore);
printf("Done\n");
getc(stdin);
}