#include <Windows.h>
#include <process.h>
#include <stdio.h>
#include <time.h>
#define NUM_THREADS 4
int N = 10000, *A;
int intTotals[NUM_THREADS], outTotals[NUM_THREADS];
HANDLE doneStep1[NUM_THREADS];
HANDLE doneStep2;
unsigned __stdcall prefixScan(LPVOID pArg)
{
if(NULL != pArg)
{
int tNum = *((int*)pArg);
int start, end, i;
int lPrefixTotal;
free(pArg);
pArg = NULL;
start = (N/NUM_THREADS)*tNum;
end = (N/NUM_THREADS)*(tNum +1);
if (tNum == (NUM_THREADS - 1))
{
end = N;
}
for (i = start + 1; i < end; i++)
{
// printf(" %d, %d\r\n", A[i-1],A[i]);
A[i] = A[i-1] + A[i];
Sleep(1);
}
intTotals[tNum] = A[end - 1];
// printf("sub = %d, from %d to %d result = %d\r\n", tNum, start, end, intTotals[tNum]);
SetEvent(doneStep1[tNum]);
WaitForSingleObject(doneStep2, INFINITE);
lPrefixTotal = outTotals[tNum];
for (i = start; i < end; i++)
{
A[i] = lPrefixTotal + A[i];
}
}
return 0;
}
int main(int argc, char * argv[])
{
int i, j;
HANDLE tHandles[NUM_THREADS];
time_t begin;
time_t end;
begin = time(NULL);
A = (int*)malloc(sizeof(int)*N);
int * p = A;
for (i = 0; i < N; i++)
{
(*p++) = i;
}
for (i = 0; i < NUM_THREADS; i++)
{
doneStep1[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
}
doneStep2 = CreateEvent(NULL, TRUE, FALSE, NULL);
for (i = 0; i < NUM_THREADS; i++)
{
int *tnum = new int;
*tnum = i;
tHandles[i] = (HANDLE)_beginthreadex(NULL, 0, prefixScan, (LPVOID)tnum, 0, NULL);
}
WaitForMultipleObjects(NUM_THREADS, doneStep1, TRUE, INFINITE);
outTotals[0] = 0;
for (j = 1; j < NUM_THREADS; j++)
{
outTotals[j] = outTotals[j - 1] + intTotals[j -1];
}
SetEvent(doneStep2);
WaitForMultipleObjects(NUM_THREADS, tHandles, TRUE, INFINITE);
end = time(NULL);
printf("total = %ld cost = %d\r\n", outTotals[NUM_THREADS -1], (end - begin));
if(NULL != A)
{
free(A);
A = NULL;
}
return 0;
}
基于windows线程的并行前缀求和
最新推荐文章于 2020-10-30 22:15:52 发布