// asynchronous_multi-core.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#pragma pack(1)
typedef struct _THREAD_SEMAPHORE_INFO {
HANDLE hHandle;
DWORD dwId;
HANDLE hSemaphore;
DWORD dwAssignIndex;
DWORD dwProcessorNumber;
}THREAD_SEMAPHORE_INFO, *PTHREAD_SEMAPHORE_INFO;
typedef struct _WORK_PROCESSOR_INFO {
DWORD dwCurrentExecute;
DWORD dwMaxExecute;
}WORK_PROCESSOR_INFO, *PWORK_PROCESSOR_INFO;
#pragma pack()
static HANDLE * g_phSemaphore = NULL;
static PTHREAD_SEMAPHORE_INFO g_pThreadInfo = NULL;
static WORK_PROCESSOR_INFO g_wpi = { 0U };
static DWORD __stdcall asynwork_thread(PVOID pParam)
{
DWORD dwExitCode;
register UCHAR uRecvData[4096];
const PTHREAD_SEMAPHORE_INFO ptsi = (PTHREAD_SEMAPHORE_INFO)pParam;
for (;;)
{
//判断当前线程是否参与工作,否则休息等待;
if (g_wpi.dwCurrentExecute != ptsi->dwProcessorNumber)
{
::WaitForSingleObject(g_phSemaphore[ptsi->dwProcessorNumber], INFINITE);
g_wpi.dwCurrentExecute = ptsi->dwProcessorNumber;
}
//工作线程等待同步recv返回的网络数据;
//recv()......
//::Sleep(1000U);//此处sleep仅作测试之用;
//立即通知下一个休息等待的线程开始工作,当前线程将执行相关的逻辑操作;
::ReleaseSemaphore(g_phSemaphore[g_pThreadInfo[ptsi->dwProcessorNumber].dwAssignIndex], 1, NULL);
//使空闲线程立即生效;
::SwitchToThread();
printf("CPU[%d]->线程[%d]正在工作(%d)......\r\n",
ptsi->dwProcessorNumber,
g_pThreadInfo[ptsi->dwProcessorNumber].dwId,
g_pThreadInfo[ptsi->dwProcessorNumber].dwAssignIndex
);
//进行调用处理逻辑;
//......
//完成相关逻辑操作准备进行休息等待;
::ReleaseSemaphore(g_phSemaphore[ptsi->dwProcessorNumber], 1, NULL);
::WaitForSingleObject(g_phSemaphore[ptsi->dwProcessorNumber], INFINITE);
}
::GetExitCodeThread(::GetCurrentThread(), &dwExitCode);
::ExitThread(dwExitCode);
return 0U;
}
static void __cdecl asynwork_del_semaphore(void)
{
register DWORD i;
if (g_phSemaphore != NULL)
{
for (i = 0U; i < g_wpi.dwMaxExecute; ++i)
{
if (g_phSemaphore[i] != NULL) {
::CloseHandle(g_phSemaphore[i]);
}
}
free(g_phSemaphore);
}
}
static void __cdecl asynwork_del_thread(void)
{
register DWORD i;
register DWORD dwExitCode;
if (g_pThreadInfo != NULL)
{
for (i = 1U; i < g_wpi.dwMaxExecute; ++i)
{
if (g_pThreadInfo[i].hHandle != NULL)
{
::GetExitCodeThread(g_pThreadInfo[i].hHandle, &dwExitCode);
::TerminateThread(g_pThreadInfo[i].hHandle, dwExitCode);
::CloseHandle(g_pThreadInfo[i].hHandle);
}
}
free(g_pThreadInfo);
}
}
static bool __cdecl asynwork_init_semaphore(DWORD dwNumberOfProcessors)
{
register DWORD i;
g_phSemaphore = (HANDLE *)malloc(
sizeof(HANDLE) * dwNumberOfProcessors
);
if (NULL == g_phSemaphore) {
return false;
}
for (i = 0U; i < dwNumberOfProcessors; ++i) {
g_phSemaphore[i] = ::CreateSemaphore(NULL, 0L, dwNumberOfProcessors, (LPCWSTR)&i);
if (NULL == g_phSemaphore[i]) {
return false;
}
else if (ERROR_ALREADY_EXISTS == ::GetLastError())
{
::CloseHandle(g_phSemaphore[i]);
return false;
}
}
return true;
}
static bool __cdecl asynwork_init_thread(DWORD dwNumberOfProcessors)
{
register DWORD i = 0U;
g_pThreadInfo = (PTHREAD_SEMAPHORE_INFO)malloc(
sizeof(THREAD_SEMAPHORE_INFO) * dwNumberOfProcessors
);
if (NULL == g_pThreadInfo) {
return false;
}
g_pThreadInfo[i].hHandle = ::GetCurrentThread();
g_pThreadInfo[i].dwId = ::GetCurrentThreadId();
g_pThreadInfo[i].hSemaphore = g_phSemaphore[i];
g_pThreadInfo[i].dwAssignIndex = i + 1;
g_pThreadInfo[i].dwProcessorNumber = i;
g_wpi.dwCurrentExecute = ::GetCurrentProcessorNumber();
for (i = i + 1U; i < (dwNumberOfProcessors - 1U); ++i)
{
g_pThreadInfo[i].hHandle = ::CreateThread(NULL, 0U,
asynwork_thread, &g_pThreadInfo[i], CREATE_SUSPENDED, &g_pThreadInfo[i].dwId);
g_pThreadInfo[i].hSemaphore = g_phSemaphore[i];
g_pThreadInfo[i].dwAssignIndex = i + 1;
g_pThreadInfo[i].dwProcessorNumber = i;
if (g_pThreadInfo[i].hHandle != NULL) {
::ResumeThread(g_pThreadInfo[i].hHandle);
}
else {
return false;
}
}
g_pThreadInfo[i].hHandle = ::CreateThread(NULL, 0U,
asynwork_thread, &g_pThreadInfo[i], CREATE_SUSPENDED, &g_pThreadInfo[i].dwId);
g_pThreadInfo[i].hSemaphore = g_phSemaphore[i];
g_pThreadInfo[i].dwAssignIndex = 0;
g_pThreadInfo[i].dwProcessorNumber = i;
if (g_pThreadInfo[i].hHandle != NULL) {
::ResumeThread(g_pThreadInfo[i].hHandle);
}
else {
return false;
}
asynwork_thread(&g_pThreadInfo[0]);
return true;
}
static bool __cdecl asynwork_start(void)
{
SYSTEM_INFO sutSystemInfo;
::GetSystemInfo(&sutSystemInfo);
g_wpi.dwMaxExecute = sutSystemInfo.dwNumberOfProcessors;
if (asynwork_init_semaphore(g_wpi.dwMaxExecute) == false)
{
asynwork_del_semaphore();
return false;
}
if (asynwork_init_thread(g_wpi.dwMaxExecute) == false)
{
asynwork_del_thread();
return false;
}
return true;
}
inline void __cdecl asynwork_free(void)
{
asynwork_del_thread();
asynwork_del_semaphore();
}
int main()
{
asynwork_start();
return 0;
}