(第6章)muduo网络库

1.muduo

  • muduo是基于Reactor模式的网络库,核心是:事件循环EventLoop,用于相应计时器和IO事件
  • muduo采用基于对象object-based,而非面向对象object-oriented的设计风格
  • muduo的核心是:每个IO线程一个事件循环,把IO事件分发到回调函数上

2.线程模型

  • muduo的线程模型是:one loop per thread+thread pool模型,每个线程最多有一个EventLoop,每个TcpConnection必须归某个EventLoop管理,所有的IO都会转移到该线程。

  • 一个file descriptor只能由一个线程读写,不同的TCP连接可以放到不同的线程中去,也可以把一些TCP连接放到一个线程里。

  • TcpServer支持多线程,由2种模式:
    (1)单线程:accept与TcpConnection用同一个线程IO
    (2)多线程:accept与EventLoop在同一个线程,另外创建一个EventLoop-ThreadPool,新到的连接会按round-robin的方式分配到线程池中

3.TCP网络编程本质

  • 基于事件的非阻塞网络编程是编写高性能并发网络服务程序的主流模式,事件处理函数也应该避免阻塞,否则会让网络服务失去响应
    其思路是:
    (1)主动调用recv来接受程序——>注册一个收数据的回调,网络库收到数据会调用我,直接把数据提供给我,供我消费
    (2)主动调用accept来接受新连接——>注册一个接受连接的回调,网络库接受了新连接会回调我,直接把新的连接对象传给我,供我使用
    (3)主动调用send来发送数据——>需要发送数据的时候,只管往连接中写,网络库会负责无阻塞地发送

  • TCP网络编程最本质的3个半事件:
    (1)消息的建立,包括服务端accept新连接和客户端connect连接。
    TCP连接一旦建立,客户端和服务端就是平等的,可以各自收发数据。
    (2)连接的断开,包括:主动断开close,shutdown和被动断开(read返回0)
    (3)消息到达,文件描述符可读。这是最为重要的一个事件,对他的处理方式决定了网络编程的风格
    (3.5)消息发送完毕,这算半个。 对于低流量的服务,可以不必关心该事件;另外,这里的 “发送完毕”指:将数据写入OS的缓冲区,将由TCP协议栈负责数据的发送与重传,不代表对方已经收到数据了。

  • 网络编程的难点如下:

1)如果主动关闭连接,如何保证对方已经收到全部数据?
(2)如果应用层有缓冲区,如何保证先发送完缓冲区的数据,然后再断开连接?
(3)如果主动发起连接,但是对方主动拒绝,如何定期(带back-off地)重试?
(4)非阻塞网络编程该用边沿触发还是电平触发?
若是电平触发,什么时候关注EPOLLOUT事件?会不会造成busy-loop?
若是边沿触发,如何防止泄读造成的饥饿?
epoll一定比poll快吗?
(5)在非阻塞网络中,为什么要使用应用层的发送缓冲区?
若应用程序要发送40KB数据,此时OS的TCP缓冲区只有25KB剩余空间,若等待OS缓冲区可用,则会
阻塞当前线程,所以可以先将剩余的15KB数据缓存在应用层的发送缓冲区中,等socket可写,再立
即发送数据。
若应用程序随后,又有50KB数据要发送,而此时发送缓冲区尚有未发送的数据,则应将50KB的数据追加
到发送缓冲区的尾部,而不要立马write,因为这可能会打乱数据的顺序!!
(6)在非阻塞网络编程中,为什么要使用应用层额接收缓冲区?
(7)在非阻塞网络编程中,如何设计并使用缓冲区?
一方面,能够减少系统调用,一次性读的数据越多越划算;
另一方面,希望能够减少内存占用;
eg:若有1000个并发连接,每个连接一建立就分配50KB的读缓冲区和50KB的写缓冲区,这将占用1GB的内存。
(8)若使用发送缓冲区,万一接收方处理缓慢,数据会不会一直堆积在发送方,造成内存暴涨?
如何做应用层的流控?
(9)如何设计并实现定时器?并使之与网路IO共用一个线程,以避免锁?

参考:<Linux多线程服务端编程:使用muduo C++网络库>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喜欢打篮球的普通人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值