77.Linux撒花
lesson52listenner会有个hander指针每遇到新链接就把这个指针注册进去相当于一个中间人拼模块main中注册lsitenner回调listenner自己不用在获得连接后注册给每一个connectionchannel内回调方法就会回调到protocol的。此时匿名对象怎么写回调函数中的参数channel可以调用到输入缓冲区 参数用的都是引用。内部就是对inbuffer进行处理的如果没读到完整报文就直接结束回调 channnel内 recv就结束就会在epoll中继续执行新数据添加到inbuff后面不管缓冲区满没满只要设置一次out关心就触发一次写事件就绪如果是满的仍然放在epoll内循环写错误码ewouldblock或者eagan就是写满了不能写了读到outbuffer有数据就直接发如果没发完开启些时间关心未来reactor当底层有空间主动wait获得时间主动sender主动发完main函数中一旦读事件就绪回调之后对报文解析上层返回发送是由epoll完成刚开始是由我自己发一次之后就不用管了。out不为空可以不发开启对写事件的关心下一次epoll自动写事件就绪看课件改多线程数据发多次可能交给不同线程两个线程竞争一个fd可能向一个socket写的顺序不一样了reactor是模块可以设计master 获得一个新链接识别到listener套接字就绪不获取连接负载均衡的分配写给管道每个slave的reactor把管道读端封装成connection添加到自己reactor所以一旦master向管道里写就通知slaveslave的ractor读时间就绪唤醒哪个进程哪个进程就调用listener模块获取连接添加到自己reactor就实现一个进程一个reactor。实现了多进程。多线程可以把管道当成套接字master和每个slaver都建立连接都用127连接本地服务就可以了主线程还是多线程共享文件描述符表master获取上来listen套接字之后往指定管道写套接字读端封装成connection添加到自己reactor一旦事件就绪就从管道读上来按四字节读文件描述符多线程也能把文件描述符拿到添加到自己reactor里多线程当中共享文件描述符表master把文件描述符拿上来同过管道添加到slaver对端拿到数字添加到自己reator里。下面代码说明fd平替管道最终方案listen套接字添加到自己所对应的reactor里有新链接到来这个reactor就会就绪然后accept获取文件描述符上面用队列和互斥锁维护socketfd池然后在master创建好几个eventfd得到文件描述符slaver把这个添加到自己reactor这个线程就可以从sockfd池把文件描述符拿到自己reactor全部由自己reactor管理这就是基于eventfd的多线程通知另外线程的做法。eventfd不设置EFD 可以当成只有一个字节的管道内核里就是一个整数以文件形式管理你写别人能读计数器变化了可以通知你添加EFD 以信号量方式工作以文件描述符方式让我们两个进程一个通过read 一个write 类似操作信号量。我们用我给对方写对方epoll就会就绪这就是做个时间通知不像管道还要从内核到用户用户到内核。所以创建多个fd把多个fd维护到master的reactor同时添加到slave的ractor里一旦事件就绪从应用层加锁维护的文件描述符集获取文件描述符不用从管道拿不用发生拷贝master把listener封装但是listrern就绪不要调用acceptlistener模块里不要包含listener套接字而是包含所有管道写端一旦listen就绪向指定管道写1唤醒后端指定进程因为子进程或新线程能读到文件描述符唤醒就能获取到新的文件描述符最佳实践listen套接字添加到自己所对应的reactor里再构建一个文件描述符集里面放vector和锁文件描述符就绪就把链接添加到这个集同时向eventfd写唤醒然后从这个集写。课堂板书/20250607_结课.png · whb-helloworld/113 - 码云 - 开源中国