多线程下的神奇的IOCP

1 篇文章 0 订阅
    一个人从接到项目到昨天终于完成,用了差不多4个月,其中各种心酸和眼泪。我的项目是通过网络从客户端上采集数据,通讯原则是客户端有数据要上传,如果网络允许就连接服务器,首先客户端发送一个消息判断服务器是不是处于忙碌和资源空闲状态,然后发送文件等等。可以说是一个基于C/S模式的多线程socket程序。


    我刚开始那到这个项目,我们经理把项目给我一看,你一个人可以做的出来吗,我一看,额。。。。。很简单吗!must,领导要求,必须做出来啊,从此在这个项目陷进去了。。。。。。
    由于以前没有做过网络方面的程序,我的开始是从传统模型开始的,就是accept一个连接就开启一个线程,这也是我那到这个项目,觉得简单的地方,很快我就实现了这个问题,我通过连接几台客户端,简单的测试一下,OK,可以正常的采集,基本的功能都可以实现。那好,我把项目一个技术经理,经理一看,小李,你效率挺快的吗,OK,你做个压力测试一下。然后我立马写了一个测试程序,写完后,我自信满满的拿给测试部门测试,我碰到了这个项目的第一个方向问题。测试部门的主管跟我说,客户端连接服务器,30、40台客户端,可以正常运行,客户端数量再往上的话,就比较容易出现乱码(也就是乱序),这个程序拿给用户不行,这是砸我们公司的招牌,我当时就懵了,怎么可能,代码没有问题啊!我回去一查,可能是粘包,我的处理方案是精简代码结构!写好后,我自己模拟用100台,测试了一晚上,没有问题,应该没有问题了吧,然后我又自信满满的拿到测试部门,我又懵了,(⊙o⊙)…,又不行,上面的问题,还是出现了,我想这是人品问题啊,怎么可能,然后在这个问题上,我纠结了差不多快两个月,代码再怎么优化都有问题,我都准备彻底放弃了!!!


    一次偶然的机会在网上看到windows操作系统有六种模型:select模型,WSAAsyncSelect异步模型,WSAEventSelect事件模型,重叠I/O事件模型,重叠I/O完成例程,IOCP完成端口。我一个一个模型差不多都用了一遍,好像都不好用,前面4种,有windows平台数量限制(64台客户端),我一看这不行,那就用IOCP吧!
    
    iocp步骤是:
    1、创建工作在线程;
       SYSTEM_INFO sysinfo;
       GetSysteminfo(&sysinfo);
       int threadcount = sysinfo.sysinfo.dwNumberOfProcessors*2;
       for (DWORD i = 0;i<sysinfo.dwNumberOfProcessors*2;i++)
       {
           HANDLE m_pWorkThread;
           m_pWorkThread = CreateThread(NULL,0,ServerWorkerThread,m_ComletionPort,0,NULL);
           CloseHandle(m_pWorkThread);
       }
    2、创建socket,不同传统模型,m_listenSock = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
    3、绑定socket,CreateIoCompletionPort((HANDLE)m_listenSock,m_ComletionPort,0,0);
    4、传统模式的bind,listen;
    5、accept(acceptex更高效),将iocp绑定客户端socket
       SOCKADDR_IN saRemote;
       int RemoteLen=sizeof(SOCKADDR_IN);
       SOCKET Accept = INVALID_SOCKET;
       Accept = WSAAccept(pDlg->m_listenSock,(SOCKADDR*)&saRemote, &RemoteLen,NULL,0));
       PerHandleData[index].Socket = Accept;
       memcpy(&PerHandleData[index].ClientAddr,&saRemote,RemoteLen);
       HANDLE m_retcompletion = CreateIoCompletionPort((HANDLE)PerHandleData[index].Socket,m_ComletionPort,(DWORD)&PerHandleData[index],0);
    6、绑定iocp成功后,投递接收请求WSARecv(PerHandleData[index].Socket, &(PerIoData[index].DataBuf), 1, &RecvBytes, &Flags,&(PerIoData[index].Overlapped), NULL);
    
    以上就是iocp的大概步骤,我使用上面的模型创建好iocp模型后,发现确实好用不少,3Mb的短连接数据传输,接收速度比传统模型几乎快了十几秒。
    
    然后我又进行了模拟100台客户端压力测试,发现运行了10几分钟系统出现崩溃,错误提示是:Debug Assertion Failed!File:Dbgheap.c Line:1011,然后我这个问题上又堵了好几天,这是什么情况呢,程序的逻辑是收完一段数据,给变一个标志位,然后通过检索这个标志位,在另外的线程处理,逻辑没有问题啊,原来windows多线程开发是线程不安全的,多线程中共享数据的访问,都要加锁。不然的话,出现内存溢出,数组越界等等奇怪的问题。
    
    还有iocp如何区分每一个socket,我是采用检索全局socket,GetQueuedCompletionStatus被激活后,将接收到的数据放到各自的全局变量区域。全局变量怎么申请呢,如果连接数量够多,申请固定大小的全局内存空间,在程序启动的时候会出现内存不足,解决办法就是在堆中申请内存(也就是malloc,注意malloc之后别忘记free,如果频繁的申请释放内存空间,容易出现磁盘碎片,不鼓励使用这种办法)。


    投递多个wsarecv有必要吗,投递多个能充分的使用cpu,这个不可否认,但是投递之后我们需要花更多的内存处理时间去组包和处理数据,如何数据还没有收完的话,还需要进一步的投递多个包,然后再组包和处理数据。。。。。。这样的效率更慢,我觉得一来一回(接收数据先判断自己的数据是否收满,没有收满再投递一个wsarecv)的方式已经可以满足自己的需要了,但是一来一回的处理方式,需要注意,GetQueuedCompletionStatus所在的工作着线程最好是不要做过多的数据处理工作,以免影响客户端发送的太快,服务器接收的太慢(如果出现这个问题,容易引起远程主机主动关闭socket错误)。


    iocp中是如何进行超时判断的?服务器资源一定,客户端如果一直连接而不发送数据或者出现各种意外客户端断开连接服务器而没有及时发现,服务器会出现资源不够用的情况,这时就要超时判断。工作者线程中记录wsarecv和WSASend操作的时间,然后再另外开一个线程判断上一次的处理wsarecv和wsasend操作跟当前时间是否超时(可以根据自己需求设定,mfc中可以使用CTimespan::GetTotalSeconds()取得时间差),如果超时就关闭socket,释放相应的内存等等。


    与IO打交道,估计是所有iocp的难题,据相关资料记载(我也不知道是在哪里看到的,IO外设的任何操作速度相对cpu处理速度来说,cpu开了1000多倍),而iocp工作者线程池设计目的为了充分发挥cpu的性能,所以工作者线程中最好不要处理IO(这就出现一个问题,空间换时间,内存不够使用)。


    工作者不处理IO,那就带来了内存的使用问题,IO处理慢,未处理的IO比较多,未处理内存积压越来越多,内存不够用。32位操作系统,内存使用机制,内核默认2G内存,程序员自己可用2G。可以通过设置c盘的boot.ini隐藏文件设置3GB程序员可用内存(具体方法可自己上网搜索)。
    

    昨天终于写好iocp服务器程序,在内存大小限制情况,短连接,每个连接都只上传6MB以内的数据,能跑500台端机,不过IO处理是关键,如果服务器忙碌的时候,在服务器上做其他操作如刷屏、打印、键盘输入数据等,会出现写文件很慢,内存很容易出现不够用的情况,不过,这已经能满足我的性能需求了。

    终于能长长的松一口气。。。。。。好开心啊!

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值