当前位置:服务器行业动态 → 正文

必发88登录:Linux高性能服务器处理框架

必发88登录,在上述合作框架下,中国海关积极开展跨境执法,2016年与美国海关针对汽车配件、药品等危害生命安全健康的重点商品开展两次联合执法行动,深入打击跨境销售网络;与俄罗斯海关针对跨境电子商务领域侵权多发高发态势,开展了邮递快件渠道联合行动;部署上海、黄埔、广州、青岛等多个口岸海关参与国际刑警组织、世界海关组织开展的区域性联合行动,此外,还与有关国家海关开展侵权案件数据交换、个案信息共享、联合风险分析等多方面的合作,取得了很好的合作成效。俄罗斯《晨报》网站2月28日报道称,翼龙Ⅱ无人机总设计师李屹东表示,这样的无人机以前只有美国有。  可以看出,如今只有高中学历,日子将会越来越不好过。据路透社2月28日报道称,美国国务院在声明中说,蒂勒森和杨洁篪在华盛顿会晤时确认了两国定期进行高层交往的重要性,并讨论了朝鲜核问题。

,杜海姆强调,就邝婉芳和余英怡一案而言,如果她们没有得到中国政府的同意,就在西班牙或其他地方获得新的身份,以新的名字生活是不合法的。参演的还包括伊斯兰革命卫队的T-72坦克、Boraq装甲运兵车(它是俄罗斯BMP-1步兵战车的伊朗改型)以及BMP-2装甲车。全年对实体经济发放的人民币贷款占同期社会融资规模增量比重为69.9%。  2016年,创业板上市公司经营业绩实现持续快速增长,高成长性优势进一步显现。

必发88登录,二是俄媒对张岚的话语理解翻译有误。 残疾预防和残疾人康复工作应当坚持以人为本,从实际出发,实行预防为主、预防与康复相结合的方针。(三)个人资料提供:1、在注册时,用户应该提供真实、准确、最新和完整的个人资料;2、如个人资料有任何变动,用户必须及时更新相关信息。第二章 义务教育 各级人民政府应当依法履行职责,保障适龄残疾儿童、少年接受义务教育的权利。

责任编辑:cres |来源:企业网D1Net  2019-07-31 16:32:24 本文摘自:简书

终于开始学习epoll了,虽然不明白的地方还是很多,但从理论到实践,相信自己动手去写一个具体的框架后,一切会清晰很多。
 
1、首先需要一个内存池,目的在于:
 
·减少频繁的分配和释放,提高性能的同时,还能避免内存碎片的问题;
 
·能够存储变长的数据,不要很傻瓜地只能预分配一个最大长度;
 
·基于SLAB算法实现内存池是一个好的思路:分配不同大小的多个块,请求时返回大于请求长度的最小块即可,对于容器而言,处理固定块的分配和回收,相当容易实现。当然,还要记得需要设计成线程安全的,自旋锁比较好,使用读写自旋锁就更好了。
 
·分配内容的增长管理是一个问题,比如第一次需要1KB空间,随着数据源源不断的写入,第二次就需要4KB空间了。扩充空间容易实现,可是扩充的时候必然 涉及数据拷贝。甚至,扩充的需求很大,上百兆的数据,这样就不好办了。暂时没更好的想法,可以像STL一样,指数级增长的分配策略,拷贝数据虽不可避免, 但是起码重分配的几率越来越小了。
 
·上面提到的,如果是上百兆的数据扩展需要,采用内存映射文件来管理是一个好的办法:映射文件后,虽然占了很大的虚拟内存,但是物理内存仅在写入的时候才会被分配,加上madvice()来加上顺序写的优化建议后,物理内存的消耗也会变小。
 
·用string或者vector去管理内存并不明智,虽然很简单,但服务器软件开发中不适合使用STL,特别是对稳定性和性能要求很高的情况下。
 
2、第二个需要考虑的是对象池,与内存池类似:
 
·减少对象的分配和释放。其实C++对象也就是struct,把构造和析构脱离出来手动初始化和清理,保持对同一个缓冲区的循环利用,也就不难了。
 
·可以设计为一个对象池只能存放一种对象,则对象池的实现实际就是固定内存块的池化管理,非常简单。毕竟,对象的数量非常有限。
 
3、第三个需要的是队列:
 
·如果可以预料到极限的处理能力,采用固定大小的环形队列来作为缓冲区是比较不错的。一个生产者一个消费者是常见的应用场景,环形队列有其经典的“锁无关”算法,在一个线程读一个线程写的场景下,实现简单,性能还高,还不涉及资源的分配和释放。好啊,实在是好!
 
·涉及多个生产者消费者的时候,tbb::concurent_queue是不错的选择,线程安全,并发性也好,就是不知道资源的分配释放是否也管理得足够好。
 
4、第四个需要的是映射表,或者说hash表:
 
·因为epoll是事件触发的,而一系列的流程可能是分散在多个事件中的,因此,必须保留下中间状态,使得下一个事件触发的时候,能够接着上次处理的位置继续处理。要简单的话,STL的hash_map还行,不过得自己处理锁的问题,多线程环境下使用起来很麻烦。
 
·多线程环境下的hash表,最好的还是tbb::concurent_hash_map。
 
5、核心的线程是事件线程:
 
·事件线程是调用epoll_wait()等待事件的线程。例子代码里面,一个线程干了所有的事情,而需要开发一个高性能的服务器的时候,事件线程应该专注于事件本身的处理,将触发事件的socket句柄放到对应的处理队列中去,由具体的处理线程负责具体的工作。
 
6、accept()单独一个线程:
 
·服务端的socket句柄(就是调用bind()和listen()的这个)最好在单独的一个线程里面做accept(),阻塞还是非阻塞都无所谓,相比整个服务器的通讯,用户接入的动作只是很小一部分。而且,accept()不放在事件线程的循环里面,减少了判断。
 
7、接收线程单独一个:
 
·接收线程从发生EPOLLIN事件的队列中取出socket句柄,然后在这个句柄上调用recv接收数据,直到缓冲区没有数据为止。接收到的数据写入以socket为键的hash表中,hash表中有一个自增长的缓冲区,保存了客户端发过来的数据。
 
·这样的处理方式适合于客户端发来的数据很小的应用,比如HTTP服务器之类;假设是文件上传的服务器,则接受线程会一直处理某个连接的海量数据,其他客户端的数据处理产生了饥饿。所以,如果是文件上传服务器一类的场景,就不能这样设计。
 
8、发送线程单独一个:
 
·发送线程从发送队列获取需要发送数据的SOCKET句柄,在这些句柄上调用send()将数据发到客户端。队列中指保存了SOCKET句柄,具体的信息 还需要通过socket句柄在hash表中查找,定位到具体的对象。如同上面所讲,客户端信息的对象不但有一个变长的接收数据缓冲区,还有一个变长的发送 数据缓冲区。具体的工作线程发送数据的时候并不直接调用send()函数,而是将数据写到发送数据缓冲区,然后把SOCKET句柄放到发送线程队列。
 
·SOCKET句柄放到发送线程队列的另一种情况是:事件线程中发生了EPOLLOUT事件,说明TCP的发送缓冲区又有了可用的空间,这个时候可以把SOCKET句柄放到发送线程队列,一边触发send()的调用;
 
·需要注意的是:发送线程发送大量数据的时候,当频繁调用send()直到TCP的发送缓冲区满后,便无法再发送了。这个时候如果循环等待,则其他用户的 发送工作受到影响;如果不继续发送,则EPOLL的ET模式可能不会再产生事件。解决这个问题的办法是在发送线程内再建立队列,或者在用户信息对象上设置 标志,等到线程空闲的时候,再去继续发送这些未发送完成的数据。
 
9、需要一个定时器线程:
 
·一位将epoll使用的高手说道:“单纯靠epoll来管理描述符不泄露几乎是不可能的。完全解决方案很简单,就是对每个fd设置超时时间,如果超过timeout的时间,这个fd没有活跃过,就close掉”。
 
·所以,定时器线程定期轮训整个hash表,检查socket是否在规定的时间内未活动。未活动的SOCKET认为是超时,然后服务器主动关闭句柄,回收资源。
 
10、多个工作线程:
 
·工作线程由接收线程去触发:每次接收线程收到数据后,将有数据的SOCKET句柄放入一个工作队列中;工作线程再从工作队列获取SOCKET句柄,查询hash表,定位到用户信息对象,处理业务逻辑。
 
·工作线程如果需要发送数据,先把数据写入用户信息对象的发送缓冲区,然后把SOCKET句柄放到发送线程队列中去。
 
·对于任务队列,接收线程是生产者,多个工作线程是消费者;对于发送线程队列,多个工作线程是生产者,发送线程是消费者。在这里需要注意锁的问题,如果采用tbb::concurrent_queue,会轻松很多。
 
11、仅仅只用scoket句柄作为hash表的键,并不够:
 
·假设这样一种情况:事件线程刚把某SOCKET因发生EPOLLIN事件放入了接收队列,可是随即客户端异常断开了,事件线程又因为EPOLLERR事 件删除了hash表中的这一项。假设接收队列很长,发生异常的SOCKET还在队列中,等到接收线程处理到这个SOCKET的时候,并不能通过 SOCKET句柄索引到hash表中的对象。
 
·索引不到的情况也好处理,难点就在于,这个SOCKET句柄立即被另一个客户端使用了,接入线程为这个SCOKET建立了hash表中的某个对象。此时,句柄相同的两个SOCKET,其实已经是不同的两个客户端了。极端情况下,这种情况是可能发生的。
 
·解决的办法是,使用socket fd + sequence为hash表的键,sequence由接入线程在每次accept()后将一个整型值累加而得到。这样,就算SOCKET句柄被重用,也不会发生问题了。
 
12、监控,需要考虑:
 
·框架中最容易出问题的是工作线程:工作线程的处理速度太慢,就会使得各个队列暴涨,最终导致服务器崩溃。因此必须要限制每个队列允许的最大大小,且需要监视每个工作线程的处理时间,超过这个时间就应该采用某个办法结束掉工作线程。

关键字:服务器

本文摘自:简书

Linux高性能服务器处理框架 扫一扫
分享本文到朋友圈

关于我们联系我们版权声明友情链接广告服务会员服务投稿中心必发88登录

企业网版权所有©2010-2019 京ICP备09108050号-6

^
博猫开户 澳门威尼斯人游戏网站 99真人网 vwin德赢
必发88登录 必发88登录 必发88登录 必发88登录
365滚球 威尼斯人注册官网 伟德体育app 利来国际官网
新宝6平台 龙八 澳门永利会官网 18luck
sitemap