windows核心编程-线程池

线程池解决多线程难于管理的问题,Windows主要提供如下方式实现

  • 异步调用函数:服务器客户端模式下比较适用
  • 定时回调函数:避免使用多个定时器占用主线程CPU处理时间
  • 内核对象通知状态回调:多个线程等待相同内核对象下适用
  • 异步IO请求完成时调用函数:异步IO操作情形下适用

 

1)异步调用函数实现

使用于服务器端创建线程处理客户端请求情景

MainThread->Wait for Client request->CreateThread handle request-> waitfor client request

使用:

服务器端收到客户端请求时调用

BOOL WINAPI QueueUserWorkItem(
  __in      LPTHREAD_START_ROUTINE Function,
  __in_opt  PVOID Context,
  __in      ULONG Flags
);

需要注意:执行过程中是无序的

 

DWORD WINAPI WorkProc(

__in  LPVOID lpParameter

)

{

DWORD dwThreadID=GetCurrentThreadId();

int i =(int)lpParameter;

printf("Thread:%d,time:%d,val:%d\n",dwThreadID,GetTickCount(),i);

return 1;

}

 

void WorkItemDemo()

{

for(int i=0;i<100;i++)

{

QueueUserWorkItem(WorkProc,(PVOID)i,WT_EXECUTEDEFAULT);

}

}

 

  

2)定时回调函数

适用于需要启动定时器且不影响主线程情形

VOID CALLBACK TimerRoutine(PVOID lpParam, BOOLEAN TimerOrWaitFired)

{

if (lpParam == NULL)

{

printf("TimerRoutine lpParam is NULL\n");

}

else

{

printf("thread:%d Timer routine called. Parameter is %d.\n",

GetCurrentThreadId(),*(int*)lpParam);

}

 

}

 

 

int _tmain(int argc, _TCHAR* argv[])

{

HANDLE hTimer[10];

HANDLE hTimerQueue=NULL;

int arg = 123;

 

// Create the timer queue.

hTimerQueue = CreateTimerQueue();

if (NULL == hTimerQueue)

{

printf("CreateTimerQueue failed (%d)\n", GetLastError());

return 2;

}

 

int iArray[10] = {0,1,2,3,4,5,6,7,8,9};

 

for(int i=0;i<10;i++)

{

// Set a timer to call the timer routine in 10 seconds.

if (!CreateTimerQueueTimer( hTimer+i, hTimerQueue,

(WAITORTIMERCALLBACK)TimerRoutine, iArray+i , 100+i*100, 100, 0))

{

printf("CreateTimerQueueTimer failed (%d)\n", GetLastError());

return 3;

}

}

 

// TODO: Do other useful work here

//WaitForMultipleObjects(10,hTimer,true,INFINITE);

Sleep(60*1000);

printf("Call timer routine in 10 seconds...\n");

 

// Delete all timers in the timer queue.

if (!DeleteTimerQueue(hTimerQueue))

printf("DeleteTimerQueue failed (%d)\n", GetLastError());

 

return 0;

 

}

  

3)内核对象通知状态回调

适用于多线程等待某个相同内核对象通知,相同等待事件可有多个回调同时进入,在对象属于通知状态时可反复调用多次….

VOID CALLBACK WaitOrTimerCallback0(

__in  PVOID lpParameter,

__in  BOOLEAN TimerOrWaitFired

)

{

//通知状态自动调用

static volatile LONG iCount=0;

int i= (int)lpParameter;

InterlockedIncrement(&iCount);

printf("Thread:%d,val:%d,count:%d\n",GetCurrentThreadId(),i,iCount);

 

}

 

//...

RegisterWaitForSingleObject(&hReg[0],hEvent,WaitOrTimerCallback0,0,100,WT_EXECUTEDEFAULT);

//…

SetEvent(hEvent);

//…

UnregisterWait(hReg[0]);

  

4)异步IO请求完成时调用函数

需要注意使用重叠模式创建文件和读写文件,读写需要调用GetOverlappedResult获取读写数据

DWORD g_DwWriten=0;

VOID CALLBACK MyFileIOCompletionRoutine(

__in  DWORD dwErrorCode,

__in  DWORD dwNumberOfBytesTransfered,

__in  LPOVERLAPPED lpOverlapped

)

{

printf("thread:%d,trans:%d\n",GetCurrentThreadId(),dwNumberOfBytesTransfered);

}

//…

hFile = CreateFile(pszFile,                // name of the write

GENERIC_WRITE,          // open for writing

0,                      // do not share

NULL,                   // default security

CREATE_ALWAYS,          // overwrite existing

FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED ,  // FILE_FLAG_OVERLAPPED重叠模式

NULL);

//…

OVERLAPPED ov;

ZeroMemory(&ov,sizeof(OVERLAPPED));

if( FALSE == WriteFile(hFile,           // open file handle

DataBuffer + dwBytesWritten,     // start of data to write

dwBytesToWrite - dwBytesWritten, // number of bytes to write

&dwBytesWritten, // number of bytes that were written

&ov)            // overlapped 重叠模式

)

{

if(GetLastError() != ERROR_IO_PENDING)

{

printf("Could not write to file (error %d)\n", GetLastError());

CloseHandle(hFile);

return 0;

}

GetOverlappedResult(hFile,&ov,&dwBytesWritten,TRUE);

}

  

 

posted @ 2013-05-19 01:25  Yarkin  阅读(1349)  评论(0编辑  收藏  举报