当前位置: 首页 > wzjs >正文

赤城网站建设上海网站快速排名提升

赤城网站建设,上海网站快速排名提升,南宁app下载,网站排名优化效果epoll设计实现 没有epoll之前,Linux只能做嵌入式 数据结构设计 fd总集:以查找为主,为啥以查找为主(往下看) 哈希表:初始化内存占用太大,比如只有100个fd,也得初始化一个1k长的哈希…

epoll设计实现

没有epoll之前,Linux只能做嵌入式

数据结构设计

  1. fd总集:以查找为主,为啥以查找为主(往下看)
    • 哈希表:初始化内存占用太大,比如只有100个fd,也得初始化一个1k长的哈希数组,造成空间浪费(现在有那种可扩展的哈希,也许能套用)
    • B树和B+树:查找速度较慢,采用划分分区的思想就行搜索,虽然树矮,但key比较次数较多
      • 一般根据上个节点查找下个节点的这种功能用B树
      • 一般用在磁盘查找上
      • 修改一个节点时只用刷新局部
    • 红黑树:维护难度较高,修改一个节点可能需要修改整棵树,但综合查找速度和存储开销,是一个较优选择
  2. 就绪fd集合:不涉及查找,只用来存储,就队列就好
    • 双向链表:链表用双向的,删除一个节点方便

协议栈如何与epoll模块通信

借助linux文件系统vfs:

20230204214300

协议栈会通过API回调epoll,epoll才知道哪些fd就绪了:

20230204220706
  • 三次握手后,内核协议栈accept()通知epoll:epollin
  • 接收到数据与确认包后,recv()通知:epollin
  • 内核协议栈tcb sendbuff发送数据后,收到ack将清空sendbuff,这时send()通知epoll:epollout
  • 接收到fin包,close() 也会通知:epollin
  • 接收到rst包:通知epollerr

epoll如何加锁

就绪队列和红黑树的节点是一个节点:

struct epitem {RB_ENTRY(epitem) rbn;LIST_ENTRY(epitem) rdlink;int rdy; //exist in list int sockfd;struct epoll_event event; 
};// epoll_create
struct eventpoll {ep_rb_tree rbr;int rbcnt;LIST_HEAD( ,epitem) rdlist;int rdnum;int waiting;pthread_mutex_t mtx; //rbtree updatepthread_spinlock_t lock; //rdlist updatepthread_cond_t cond; //block for eventpthread_mutex_t cdmtx; //mutex for cond#if ENABLE_MUL_EPOLLstruct eventpoll *prev;struct eventpoll *next;
#endif
};
20230204220850

多个线程操作epoll:

  1. epoll_ctrl:对红黑树加锁
    • 锁整棵树
    • 锁子树
    • 锁类型:互斥锁 =》没有获取到锁,让出cpu资源
  2. epoll_wait:对就绪队列加锁
    • 是协议栈回调后操作就绪队列,用户态只是读队列,这个锁是为协议栈设置的
    • 锁类型:自旋锁 =》没有获取到锁,cpu资源不让出,就等着有资源释放锁
    • 队列为啥用自旋锁:因为队列操作简单,占着cpu资源并等待的开销,小于让出cpu资源再重新获取cpu资源的
    • 还得设置条件等待:因为队列可能为空0,抢到锁了还要等到队列不为空才能取数据(线程池同理)
  3. epoll_create:不加锁
    • 锁是epoll的一部分,锁也需要通过epoll_create进行初始化(也就是初始化eventpoll),即使多个线程创建多个epoll,那也不会造成数据错误

et与lt如何实现

比如客户端发4k的数据,服务器只接收1k,recv先读1k,调用回调,如果是边缘触发,后面的3k是不会触发的(如果客户端再发1k,这次也是会触发的),但水平触发还会触发3次

只要没读完,就会一直recv,每次调用recv都会触发

et:接收数据,调用一次回调,就是一次要把缓存区的数据全部读完

lt: recvbuffer里面有数据,就回调(如果节点已经在就绪队列里了,就不用管)

在接收缓冲区数据的时候,协议栈如果一次接收完就循环接收,接收一次就回调一次epoll:

// 可以这么理解
for(length = 0;Pay_loadLen != 0;length += recvlen){recvlen = recv(remote_fd, ReceiveBuff, Pay_loadLen, 0);Pay_loadLen = Pay_loadLen - recvlen;memcpy(RxBuffer+length, ReceiveBuff, recvlen);memset(ReceiveBuff, 0, sizeof(ReceiveBuff));// epoll_cb();	    // 在这里回调是水平触发
}
// 在这里回调是边缘触发

tip:

  1. epoll中并没用mmap(磁盘与内存的映射),有的文章说会将就绪队列映射到用户态,使得就绪队列也无需从内核态拷贝到用户态,但代码中并没有。
  2. aio并不是适合做网络IO(网络IO最高效的还是reactor模型),更适合做磁盘IO
  3. 内核协议栈本身也是支持mba实现共享内存的,只是有些网卡不支持
  4. 共享内存:
    • 一般用来做进程间通信(IPC),是一块物理内存,多进程通过页表将各自的虚拟地址映射到这块物理内存,实现内存共享,但共享内存没有做进程间同步和互斥机制,需要结合信号量使用
    • 这里主要是用来实现零拷贝,将磁盘映射到内存。(严格来说应该都不叫共享内存。只是进行了内存映射)
  5. 用户态协议栈也得设计用户态epoll,因为用户态协议栈中的 fd 是用户态的,没法调内核态的epoll
http://www.dtcms.com/wzjs/420737.html

相关文章:

  • 张北网站建设上海有名网站建站开发公司
  • 瑞达恒建筑网站seo排名怎么做
  • 网站开发四川百度关键词排名神器
  • 阆中市网站建设百度公司简介介绍
  • 制作公司网站有哪些山西seo优化公司
  • 查看注册过的网站百度资源搜索引擎
  • javaweb源码分享网站如何发布自己的广告
  • 网站建设找客户公司地址怎么弄在百度上显示
  • 学校做网站需要什么免费的h5制作网站模板
  • 建设一个网站流程图最新病毒感染什么症状
  • wordpress 自动内链 代码seo推广如何做
  • 网站的功能包括哪些内容整站排名优化品牌
  • 徐州做网站的公司有几家百度搜索推广开户
  • 手机网页微信seo全网推广营销软件
  • 重庆网站排名推广武汉大学人民医院精神卫生中心
  • 怎么用代码做网站推荐青岛网站建设有限公司
  • 音乐版权购买网站成都进入搜索热度前五
  • 厦门网站制作开发收费网站备案查询系统
  • 网站快排是怎么做的b2b平台推广
  • 深圳公司网站开发杭州百度seo代理
  • 做模具的都有什么网站网络服务器图片
  • wordpress 星星评分公司seo是什么意思
  • 网站建设自助建站企业成人本科报考官网
  • 做网站的图片取材百度网盘资源免费搜索引擎入口
  • 上海网站关键词优化seo搜索优化专员招聘
  • 万网网站备案查询长春做网站公司长春seo公司
  • 公司创建的法制网站企业策划书
  • 省级示范校建设专题网站湖人最新消息
  • 西宁市城中区建设局网站企业关键词推广
  • wordpress 面包屑导航湖南seo推广多少钱