Reputation: 122
I'm trying to run 3 threads in the same time and then detect in main thread which one has finished. I'm using WaitForMultipleObject function but 3rd thread seems to loop for this WFMO function, while it has already finished its job (printed result).
#include <Windows.h>
#include <stdio.h>
#include <conio.h>
//---------------------------------------------------------------------------
#pragma argsused
struct data
{
char name[50];
} data[3] = { { "[THREAD 0]" }, { "[THREAD 1]" },{ "[THREAD 2]" } };
DWORD WINAPI th0()
{
//here are some calculations
//also added 1s sleep
//printing result
return 0;
}
DWORD WINAPI th1()
{
//here are some other calculations
//also added 1s sleep
//printing result
return 0;
}
DWORD WINAPI th2()
{
//here are some other simple calculations
//also added 1s sleep
//printing result
return 0;
}
int priority[3] = { 0,0, 0};
HANDLE threads[3];
HANDLE functions[3];
int main(int argc, char **argv)
{
int i;
DWORD id; // thread's id
printf("Program started...\n");
functions[0] = th0;
functions[1] = th1;
functions[2] = th2;
for (i = 0; i < 3; i++)
{
threads[i] = CreateThread(
NULL, // security atributes
0, // stack size
(LPTHREAD_START_ROUTINE)functions[i], // threads
NULL,// input data for threads
0, // creation's flags
&id);//thread's id
if (threads[i] != INVALID_HANDLE_VALUE)
{
printf("Created thread %s with ID: %x\n",
data[i].name, id);
SetThreadPriority(threads[i], priority[i]);
}
}
bool f0=false, f1=false, f2=false;
while(!f0 || !f1 || !f2)//while there is any unfinished thread
{
DWORD wfmo = WaitForMultipleObjects(3, threads, false, INFINITE);
if (!f0 && WAIT_OBJECT_0==wfmo)
{
printf("%s is done!\n", data[0].name);
f0=true;
//CloseHandle(threads[0]);
//threads[0]=NULL;
}
if (!f1 && WAIT_OBJECT_0 +1 == wfmo)
{
printf("%s is done!\n", data[1].name);
f1=true;
//CloseHandle(watki[1]);
//watki[1]=NULL;
}
if (!f2 && WAIT_OBJECT_0 +2 == wfmo)
{
printf("%s is done!\n", data[2].name);
f2=true;
//CloseHandle(threads[2]);
//threads[2]=NULL;
}
if(wfmo==WAIT_TIMEOUT)
printf("timeout\n");
if(wfmo==WAIT_FAILED)
printf("failed\n");
}
//Sleep(20000); //20s
return 0;
}
Output:
Program started...
Created thread [THREAD 0] with ID: b00
Created thread [THREAD 1] with ID: a64
Created thread [THREAD 2] with ID: 7d0
[THREAD 2] Result: 131072
[THREAD 1] Result: 121393
[THREAD 0] Result: 362880
[THREAD 2] is done!
[THREAD 0] is done!
Upvotes: 2
Views: 3256
Reputation: 122
Solution (instead of while loop):
DWORD wfmo = WaitForMultipleObjects(3, threads, false, INFINITE);
//HANDLE threads2[2];
if ( WAIT_OBJECT_0==wfmo)//move th1 and th2 up
{
printf("%s is done!\n", data[0].name);
threads[0]=threads[1];
threads[1]=threads[2];
data[0]=data[1];
data[1]=data[2];
threads[2]=NULL;
}
else if ( WAIT_OBJECT_0 +1 == wfmo) //move th2 up
{
printf("%s is done!\n", data[1].name);
threads[1]=threads[2];
data[1]=data[2];
threads[2]=NULL;
}
else if ( WAIT_OBJECT_0 +2 == wfmo)//no need to do anything
{
printf("%s is done!\n", data[2].name);
threads[2]=NULL;
}
wfmo = WaitForMultipleObjects(2, threads, false, INFINITE);
if ( WAIT_OBJECT_0==wfmo)
{
printf("%s is done!\n", data[0].name);
threads[0]=threads[1];
data[0]=data[1];
threads[1]=NULL;
}
else if ( WAIT_OBJECT_0 +1 == wfmo)
{
printf("%s is done!\n", data[1].name);
threads[1]=NULL;
}
wfmo = WaitForMultipleObjects(1, threads, false, INFINITE);
if ( WAIT_OBJECT_0==wfmo)
printf("%s is done!\n", data[0].name);
Upvotes: 0
Reputation: 6145
From the MSDN WaitForMultipleObjects
documentation :
If bWaitAll is FALSE, the return value minus WAIT_OBJECT_0 indicates the lpHandles array index of the object that satisfied the wait. If more than one object became signaled during the call, this is the array index of the signaled object with the smallest index value of all the signaled objects.
Once the thread 0 is finished, the return value will always be WAIT_OBJECT_0
.
Upvotes: 1