muduo buffer

网络模型

  • nonblocking + IO多路复用
    原因:
    1.nonblock io + 轮询等待事件完成不可取 (耗CPU cycle)
    2.IO多路复用不能用block IO,因为read,write会阻塞当前线程,这样就不能单线程处理另外已经就绪的其他connfd IO事件

  • 一个线程一个eventloop,高效的eventloop(libevent, libev)

  • 多个TCPServer和TCPClient可以共享同一个eventloop

文件传输

  • 使用TcpConn::send(),send保证数据会发送给对方,send是非阻塞的(即使output buffer满了,也不会阻塞当前线程),send是线程安全的(消息不会混叠交织,多线程发送顺序不确定)
  • 非阻塞网络编程中,发送消息由muduo完成,用户不需调用write或send等系统调用,因此TcpConn需要有output buffer
  • send(const Slice&)可以发送string和char,send(Buffer)不用const引用,是因为函数可能用Buffer::swap交换数据,避免内存拷贝(类似右值引用)

muduo buffer

  • 为什么nonblock网络编程需要buffer?
    因为要避免epoll_wait之外的阻塞,每个tcp socket都要有stateful的inputbuffer(read),outputbuffer(write)
    tcpconn需要output buffer,为了避免一次send只发送一部分数据,如80k/100K(因为操作系统write一次只接受80k),注册epoll_out事件,一旦可写就立即发送,写完了就关闭这个事件,如果程序又写了50k,应该把这数据放入buffer而不是直接write,如果buffer还有数据就不能直接关闭连接,而要等待数据发送完
    tcpconn需要input buffer,网络库处理socket可读事件时,要一次把socket数据读完(从OS搬到应用层),否则会频繁POLLIN,造成busyloop

  • buffer的结构?

  • Buffer不是线程安全的

  • 替换vector?
    可以用circular buffer,可以减少内部挪腾(前面+后面可以填充数据,需要[read_idx~write_idx]挪到前面去)

  • zero copy?
    原来需要把数据copy进vector,可以参考libevent,用链表把数据块连起来,但高性能的代价是代码不太好懂

  • 性能问题?




posted @ 2022-09-06 17:05  misaka-mikoto  阅读(56)  评论(0编辑  收藏  举报