完成端口模型,PostQueuedCompletionStatus后,GetQueuedCompletionStatus不响应,详见内容

whichname whichname 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
大致代码如下:
#define THREAD_NUM (3) //线程数

typedef unsigned int DIS_ID_t;

enum TIMER_TYPE
{
E_TIMER_1,
E_TIMER_2,
E_TIMER_3,
};

class CPrint
{
public:
CPrint()
{
InitializeCriticalSection( &m_cs );
}

~CPrint()
{
DeleteCriticalSection( &m_cs );
}

void Print(std::string str)
{
::EnterCriticalSection(&m_cs);
std::cout << str.c_str() << std::endl;
::LeaveCriticalSection(&m_cs);
}

static CPrint *Instannce()
{
if (NULL == m_CPrint)
{
return m_CPrint = new CPrint;
}

return m_CPrint;
}

private:
static CPrint *m_CPrint;
CRITICAL_SECTION m_cs;
};

CPrint *CPrint::m_CPrint = NULL;

DWORD __stdcall ThreadPro( void* pArguments );
class CThread
{
public:
CThread()
{
}

~CThread()
{
}

void InitData(void)
{
m_hThreadPool = CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,NULL,0);
for (int i=0; i<THREAD_NUM; i++)
{
m_Thread[i] = CreateThread( NULL,0,ThreadPro,NULL,0,NULL );
}
}

static HANDLE m_hThreadPool;
static OVERLAPPED m_ThreadOvl;
private:
HANDLE m_Thread[THREAD_NUM];
};

HANDLE CThread::m_hThreadPool = NULL;
OVERLAPPED CThread::m_ThreadOvl;

DWORD __stdcall ThreadPro( void* pArguments )
{
while (1)
{
DWORD dwTrans;
DWORD dwKey;
LPOVERLAPPED ovlop;
BOOL bRet = GetQueuedCompletionStatus( CThread::m_hThreadPool,&dwTrans,(PULONG_PTR)&dwKey,&ovlop,INFINITE );
if(bRet)
{
DIS_ID_t disID = *((DIS_ID_t *)dwKey);

if (disID == E_TIMER_1)
{
CPrint::Instannce()->Print("++++++++定时器1");
}
else if (disID == E_TIMER_2)
{
CPrint::Instannce()->Print("++++++++定时器2");
}
else
{
CPrint::Instannce()->Print("++++++++定时器3");
}
}
else
{
break;
}
}

return 0;
}

struct stTimer
{
DIS_ID_t m_Type;
DWORD m_LastTime;
DWORD m_Interval;
};

int _tmain(int argc, _TCHAR* argv[])
{
CThread thread;
thread.InitData();

std::vector<stTimer> timerList;

stTimer timer1,timer2,timer3;

DWORD initTime = (DWORD)time(NULL);
timer1.m_LastTime = initTime;
timer1.m_Interval = 10; //10秒
timer1.m_Type = E_TIMER_1;

initTime = (DWORD)time(NULL);
timer2.m_LastTime = initTime;
timer2.m_Interval = 60; //60秒
timer2.m_Type = E_TIMER_2;

initTime = (DWORD)time(NULL);
timer3.m_LastTime = initTime;
timer3.m_Interval = 60; //60秒
timer3.m_Type = E_TIMER_3;

timerList.push_back(timer1);
timerList.push_back(timer2);
timerList.push_back(timer3);

unsigned int i = 0;
while (i < 0xffff)
{
DWORD curTime = (DWORD)time(NULL);
std::vector<stTimer>::iterator it = timerList.begin();
for (; it != timerList.end(); it++)
{
DWORD interval = curTime - it->m_LastTime;
if (interval > it->m_Interval)
{
DIS_ID_t disID = it->m_Type;
PostQueuedCompletionStatus( CThread::m_hThreadPool,sizeof(disID),(DWORD)(INT_PTR)&disID,&CThread::m_ThreadOvl);
it->m_LastTime = curTime;

if (it->m_Type == E_TIMER_1)
{
CPrint::Instannce()->Print("---------------定时器1");
}
else if (it->m_Type == E_TIMER_2)
{
CPrint::Instannce()->Print("---------------定时器2");
}
else
{
CPrint::Instannce()->Print("---------------定时器3");
}
}
}

if ((i % 8) == 0)
{
CPrint::Instannce()->Print("oooooooooo");
}

i++;
Sleep(1000);
}

return 0;
}


在CThread::InitData(void)中创建了3个工作线程,
在主线程中设置3个定时器,

当时间到了就执行PostQueuedCompletionStatus,
工作线程响应。

现在的问题是:
当定时器E_TIMER_2, E_TIMER_3设置时间间隔一样,切启动时间一样
则可能会出现问题:定时器E_TIMER_2不响应,但定时器可能会响应2次,
怀疑是控制台输出的原因,但控制台输出都加了锁,
且在定时器E_TIMER_2的响应代码处段点在连续多个时间间隔都不会触发,之后也许很久会触发一次

感觉有点诡异,请不吝赐教!!!
...全文

相关推荐

完成端口 实例 .net

完成端口(IO Completion Ports, I/OCP)是Windows操作系统中一种高效的I/O模型,尤其适用于高并发的网络服务。

youlxsbobo

深入掌握Windows IOCP高性能编程

本文还有配套的精品资源,点击获取 简介:完成端口(IOCP)是Windows中的高效I/O模型,用于高效处理并发I/O操作。本压缩包包含的源码和示例文件旨在帮助开发者深入理解并实践完成端口的使用,涵盖线程池使用、异步I/O操作、完成队列管理、I/O状态获取和自定义完成信息处理。通过这些实践,开发者能够掌握如何提升网络服务器性能,实现高效多路复用,并增强应用程序处理并发连接的...

含老司开挖掘机

Windows高性能网络编程:IOCP完成端口模型原理与MFC服务端实战

在服务器开发中,处理高并发连接是核心挑战。传统同步阻塞模型如select存在效率瓶颈,而异步I/O模型通过非阻塞操作和事件通知机制,实现了更高的吞吐量和资源利用率。IOCP(I/O Completion Ports,完成端口)是Windows平台下最成熟的异步I/O解决方案,其核心原理是将I/O操作与线程调度解耦。当应用程序发起异步网络请求后,系统内核在操作完成后通过完成端口队列通知工作线程,避免了线程轮询开销。这种模型能有效利用多核CPU,实现真正的可伸缩性,尤其适合需要处理成千上万并发连接的TCP服务端

weixin_34318272

IOCP完成端口模型

**C++**作为编程语言,在实现IOCP模型时,可以利用Windows API提供的CreateIoCompletionPort、GetQueuedCompletionStatus和PostQueuedCompletionStatus

maoxiaojiao

手把手教你玩转网络编程模型之完成端口(CompletionPort)篇[归纳].pdf

**异步通信**:与传统的同步通信模型相比,完成端口支持异步操作,不会因单个通信任务阻塞而影响其他任务执行,保证了服务端的响应速度。3.

cyh76339129
评论 2
收藏 已收藏
分享
返回顶部
whichname
VC/MFC 16,550 成员 421,606 内容