zoukankan      html  css  js  c++  java
  • 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);
    
    }
    

      

     

  • 相关阅读:
    How to resolve mysql problem when you get code 2003(10061) and 1130
    Windows connect to mysql failed: can't get hostname for your address
    Python基础教程总结(二)
    Python基础教程总结(一)
    Begin to study Deep Learning
    再坚持一点点
    技术到管理的必经之路(2)
    技术到管理的必经之路(1)
    c#进阶(7)—— 异步编程基础(async 和 await 关键字)
    c#进阶(6)—— 网络通信基础知识
  • 原文地址:https://www.cnblogs.com/SkyMouse/p/3086447.html
Copyright © 2011-2022 走看看