window线程池

window提供了线程池机制,方便开发。这些线程池函数允许我们做以下事情:
1.以异步方式来调用一个函数。
2.每个一段时间调用一个函数
3.当内核对象触发时调用一个函数
4.当异步IO请求完成时调用一个函数

一、以异步方式调用一个函数:
相关API:TrySubmitThreadPoolCallback
回调函数原型:VOID NTAPI SimpleCallback(PTP_CALLBACK_INSTANCE pInstance,PVOID pvContext)
简单的封装,免得每次使用都要记住api和回调函数的原型。
class IAsOpThread
{
public:
virtual void ThreadProc() = 0;
bool Start()
{
//TrySubmitThreadpoolCallback 可能失败,这时候线程不会被启动,所以这里重试
int tryCount = 0;
bool ret = TrySubmitThreadpoolCallback(IAsOpThread::SimpleCallback, this, NULL);
while (!ret && tryCount < 3)
{
ret = TrySubmitThreadpoolCallback(IAsOpThread::SimpleCallback, this, NULL);
++tryCount;
}
return ret;
}


private:
static VOID CALLBACK SimpleCallback(PTP_CALLBACK_INSTANCE Instance, PVOID pContext)
{
static_cast<IAsOpThread*>(pContext)->ThreadProc();
}
};

class NormalWork: public IAsOpThread
{
public:
NormalWork()
{}
~NormalWork()
{}

void ThreadProc() override
{
cout << "NormalWork" << endl;
}
};

int _tmain(int argc, _TCHAR* argv[])
{
NormalWork normalWork;
normalWork.Start();
system("pause");
return 0;
}

显示控制工作项
TrySubmitThreadpoolCallback调用时,系统会分配一个工作项,如果需要频繁提交大量工作项,对于性能和内存使用的考虑,我们可以创建一个工作项,然后分多次提交。之前的项目中需要频繁的计算文件块的校验信息,由于计算校验信息的算法逻辑时一样的,每次提交请求只是设置个别参数即可。这时就适用这种方式。

class IAsOpThread
{
public:
virtual void ThreadProc() = 0;
virtual ~IAsOpThread()
{
CloseThreadpoolWork(m_pwk);
}
bool Start()
{
m_pwk = CreateThreadpoolWork(IAsOpThread::WorkCallback, this, NULL);
SubmitThreadpoolWork(m_pwk);
Sleep(1000);
return true;
}


private:

static VOID CALLBACK WorkCallback(PTP_CALLBACK_INSTANCE Instance, PVOID pContext, PTP_WORK Work)
{
static_cast<IAsOpThread*>(pContext)->ThreadProc();
}
PTP_WORK m_pwk;
};

class NormalWork: public IAsOpThread
{
public:
NormalWork()
{}
~NormalWork()
{}
void SetFileOffset(int offset)
{
m_offset = offset;
}

void ThreadProc() override
{
cout << "current threadid :" << GetCurrentThreadId() << endl;
cout << "offset:" << m_offset << endl;
cout << "calc verify info" << endl;
}

private:
int m_offset{0};
};
int _tmain(int argc, _TCHAR* argv[])
{
NormalWork normalWork;
cout << "start work" << endl;
normalWork.Start();
normalWork.SetFileOffset(100);
normalWork.Start();
normalWork.SetFileOffset(200);
normalWork.Start();
system("pause");
return 0;
}

二、每隔一段时间调用一个函数
相关api: CreateThreadpoolTimerSetThreadpoolTimerIsThreadpoolTimerSetWaitForThreadpoolTimerCallbacksCloseThreadpoolTimer
回调函数的原型:
VOID CALLBACK TimerCallback( [ in , out ] PTP_CALLBACK_INSTANCE Instance, [ in , out , optional] PVOID Context, [ in , out ] PTP_TIMER Timer );

class ThreadPoolTimer
{
public:

virtual ~ThreadPoolTimer()
{
KillTimer();
}

virtual void WorkProc()
{
cout << "base timer do nothing" << endl;
}
void SetTimer(int dueTime,int period)
{
m_pTimer = CreateThreadpoolTimer(ThreadPoolTimer::TimerCallback, this, NULL);
ULARGE_INTEGER ulRelativeStartTime;
ulRelativeStartTime.QuadPart = (LONGLONG)-dueTime * 100000*100;
FILETIME ftRelativeStartTime;
ftRelativeStartTime.dwHighDateTime = ulRelativeStartTime.HighPart;
ftRelativeStartTime.dwLowDateTime = ulRelativeStartTime.LowPart;
SetThreadpoolTimer(m_pTimer, &ftRelativeStartTime, period * 1000, 0);
}

bool IsTimerSet()
{
return m_pTimer && IsThreadpoolTimerSet(m_pTimer);
}

void KillTimer()
{
if (m_pTimer)
{
CloseThreadpoolTimer(m_pTimer);
}
}
private:

static VOID CALLBACK TimerCallback(PTP_CALLBACK_INSTANCE Instance, PVOID pContext, PTP_TIMER Timer)
{
static_cast<ThreadPoolTimer*>(pContext)->WorkProc();
}
PTP_TIMER m_pTimer{NULL};
};
int _tmain(int argc, _TCHAR* argv[])
{
ThreadPoolTimer threadTimer;
threadTimer.SetTimer(3, 0);
system("pause");
return 0;
}

三、中内核对象被触发时调用一个函数
回调函数原型
VOID CALLBACK WaitCallback(PTP_CALLBACK_INSTANCE pInstance,PVOID Context, PTP_WAIT Wait, TP_WAIT_RESULT WaitResult);
相关api:CreateThreadPoolWait,SetThreadPoolWait,
线程池中内部会让一个线程调用WaitForMultipleObjects函数,传入通过SetThreadPoolWait注册的一组句柄。由于WaitForMultipleObjects不允许我们将同一个句柄传入多次,因此我们必须确保不会SetThreadPoolWait来多次注册一个句柄。

VOID CALLBACK WaitCallbackWorkThread(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WAIT Wait, TP_WAIT_RESULT WaitResult)
{
cout << "this is a WaitCallback fun" << endl;;
}

int _tmain(int argc, _TCHAR* argv[])
{
PTP_WAIT pw = CreateThreadpoolWait(WaitCallbackWorkThread, NULL, NULL);
HANDLE h = CreateEvent(NULL, TRUE, FALSE, NULL);
SetThreadpoolWait(pw, h, NULL);
Sleep(3000);
//触发内核对象
SetEvent(h);
WaitForThreadpoolWaitCallbacks(pw, TRUE);
CloseThreadpoolWait(pw);
CloseHandle(h);
system("pause");
return 0;
}

四、中异步IO请求完成时调用一个函数
回调函数原型:
VOID CALLBACK overlappedCompletionRoutine(PTP_CALLBACK_INSTANCE pInstance, UNLOG IoResult,ULONG_PTR NumberOfBytesTransferred,PTP_IO pIo)
相关api: CreateThreadpoolIoStartThreadpoolIoCancelThreadpoolIoCloseThreadpoolIoWaitForThreadpoolIoCallbacks
VOID CALLBACK IoCompletionWorkThread4(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PVOID Overlapped, ULONG IoResult, ULONG_PTR NumberOfBytesTransferred, PTP_IO Io)
{
cout<<"this is a IoCompletionCallback fun"<<endl;
}


int _tmain(int argc, _TCHAR* argv[])
{
//打开D盘下文件a.txt
HANDLE h = CreateFile(_T("D:\\log_network.txt"), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, NULL);
PTP_IO pi = CreateThreadpoolIo(h, IoCompletionWorkThread4, NULL, NULL);
StartThreadpoolIo(pi);
OVERLAPPED ol;
ZeroMemory(&ol, sizeof(OVERLAPPED));
char c[1024] = {0};
DWORD readbytes = 0;
if (!ReadFile(h, c, 1024, &readbytes, &ol))
{
if (ERROR_IO_PENDING != GetLastError())
{
CancelThreadpoolIo(pi);
}
}
Sleep(2000);
WaitForThreadpoolIoCallbacks(pi, TRUE);
CloseThreadpoolIo(pi);
system("pause");
return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值