该实例代码展示了如何根据CPU的核数开辟多个线程,并且实现线程同步。
#include "stdafx.h"
#include "stdio.h"
#include "windows.h"
#include <conio.h>
#include <process.h>
#define MAX_THREAD_COUNT 16
typedef struct _THREAD_PARAMS
{
UINT threadId;
HANDLE threadHandle;
HANDLE threadEvent;
HANDLE threadDoneEvent;
BOOL threadShouldExit;
} THREAD_PARAMS;
THREAD_PARAMS *ThreadParams = NULL;
int ThreadCount = 0;
BOOL success;
BOOL StartWorkerThreads();
void StopWorkerThreads();
unsigned __stdcall ThreadFunc(void* pArguments);
int main(int argc, char* argv[])
{
success = StartWorkerThreads();
int threadIndex;
for(threadIndex = 0; threadIndex < ThreadCount; threadIndex++)
{
THREAD_PARAMS *pThreadParams = &ThreadParams[threadIndex];
// 利用SetEvent将ThreadEvent设置为触发状态,这样的话,等待ThreadEvent的线程就会处于触发状态。
if (!SetEvent(pThreadParams->threadEvent))
{
printf("Error: SetEvent failed -- %u", GetLastError());
success = FALSE;
break;
}
}
// Wait for all the worker threads to complete processing
for (threadIndex = 0; (threadIndex < ThreadCount) && success; threadIndex++)
{
DWORD result = WaitForSingleObject(ThreadParams[threadIndex].threadDoneEvent, INFINITE);
if (result != WAIT_OBJECT_0)
{
printf("Error: WaitForSingleObject failed -- %u\n", GetLastError());
success = FALSE;
}
}
StopWorkerThreads();
system("pause");
}
BOOL StartWorkerThreads()
{
StopWorkerThreads();
// Find the number of processor cores available
SYSTEM_INFO systemInfo;
memset(&systemInfo, 0, sizeof(systemInfo));
GetSystemInfo(&systemInfo);
DWORD processorCount = systemInfo.dwNumberOfProcessors;
// Start one worker thread per processor core, up to the specified limit
int threadCount;
if (processorCount < 1)
threadCount = 1;
else if (processorCount > MAX_THREAD_COUNT)
threadCount = MAX_THREAD_COUNT;
else
threadCount = processorCount;
// Allocate a THREAD_PARAM structure for each thread
size_t allocBytes = threadCount * sizeof(THREAD_PARAMS);
ThreadParams = (THREAD_PARAMS*) malloc(allocBytes);
if (ThreadParams == NULL)
{
printf("Error: Alloc %u bytes failed", allocBytes);
return FALSE;
}
memset(ThreadParams, 0, allocBytes);
ThreadCount = threadCount;
// Create worker threads
for (int threadIndex = 0; threadIndex < threadCount; threadIndex++)
{
THREAD_PARAMS *pThreadParams = &ThreadParams[threadIndex];
// The main thread signals a worker thread with this event
//该threadEvent自动重置,且初始状态为无信号状态。
pThreadParams->threadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (pThreadParams->threadEvent == NULL)
{
printf("Error: Create thread event failed -- %d", GetLastError());
return FALSE;
}
// The worker thread signals the main thread with this event
pThreadParams->threadDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (pThreadParams->threadDoneEvent == NULL)
{
printf("Error: Create thread event failed -- %d", GetLastError());
return FALSE;
}
// Create the worker thread
pThreadParams->threadShouldExit = FALSE;
pThreadParams->threadHandle = (HANDLE) _beginthreadex(NULL, 0, ThreadFunc, pThreadParams, 0, &pThreadParams->threadId);
if (pThreadParams->threadHandle == NULL)
{
printf("Error: Create thread failed -- %d", GetLastError());
return FALSE;
}
}
return TRUE;
}
//----------------------------------------------------------------------------
//
// Function : StopWorkerThreads
//
// Description : Stop the worker threads started by StartWorkerThreads
//
//----------------------------------------------------------------------------
void StopWorkerThreads(void)
{
if (ThreadParams != NULL)
{
for (int threadIndex = 0; threadIndex < ThreadCount; threadIndex++)
{
THREAD_PARAMS *pThreadParams = &ThreadParams[threadIndex];
// Exit the thread
if (pThreadParams->threadHandle != NULL)
{
pThreadParams->threadShouldExit = TRUE;
//当线程结束运行的时候,利用SetEvent将threadEvent置于有信号的状态,
//这样等待该threadEvent的线程将处于可调度的状态。
if (!SetEvent(pThreadParams->threadEvent))
{
printf("Error: SetEvent failed -- %d", GetLastError());
}
//当线程结束运行时,threadHandle将处于有信号状态,
//这时候WaitForSingleObject函数将返回。
WaitForSingleObject(pThreadParams->threadHandle, INFINITE);
CloseHandle(pThreadParams->threadHandle);
pThreadParams->threadHandle = NULL;
pThreadParams->threadId = 0;
}
// Close notify event handle
if (pThreadParams->threadEvent != NULL)
{
CloseHandle(pThreadParams->threadEvent);
pThreadParams->threadEvent = NULL;
}
// Close processing complete event handle
if (pThreadParams->threadDoneEvent != NULL)
{
CloseHandle(pThreadParams->threadDoneEvent);
pThreadParams->threadDoneEvent = NULL;
}
}
// Free THREAD_PARAMS structures
free(ThreadParams);
ThreadParams = NULL;
}
ThreadCount = 0;
}
unsigned __stdcall ThreadFunc(void* pArguments)
{
THREAD_PARAMS *pThreadParams = (THREAD_PARAMS*) pArguments;
for (;;)
{
// 等待主线程将threadEvent置于有信号的状态。
WaitForSingleObject(pThreadParams->threadEvent, INFINITE);
if (pThreadParams->threadShouldExit)
break;
printf("hello!\n");
// 通知主线程该线程运行结束。
SetEvent(pThreadParams->threadDoneEvent);
}
return 0;
}