《muduo学习》总结

  1. 析构的安全性
    在多线程中,两个裸指针指向同一个对象是不安全的,无法保证析构的正确性,一个线程在析构一个对象而同时另一个线程在使用它,即一个线程不能确定是否对象已经完全死掉,有可能另一处析构函数正在执行。
    shared_ptr可以保证在所有地方都不再使用时才释放,之前保证资源的有效性。
    2.shared_ptr的线程安全
    shared_ptr可以实现线程安全的释放对象,但shared_ptr本身不是线程安全的!如果一个shared_ptr对象可以被几个线程同时看到,那么读写这个对象就需要加锁!因为它内部有两个数据成员,读写操作不能原子化。
    shared_ptr的复制开销比原始指针高,一个线程只需要在最外层函数有一个实体对象,之后就可以传引用。
    将shared_ptr绑定到回调函数里会延长对象的生命周期,有时不是我们希望的,可以绑定weak_ptr到回调函数,在使用时尝试lock提升为shared_ptr,提升不成功就不调用,即陈硕所说的弱回调。
  2. 关于http可以看这篇文章:https://segmentfault.com/a/1190000011172823,关于http1.1和http2.0同时发送多个请求的区别。
  3. 每个文件描述符只由一个线程操作,既能解决收发顺序问题,也避免关闭文件描述符引起的race condition, 一个线程可以操作多个fd,但一个线程不能操作别的线程拥有的文件描述符。
    epoll也一样,应该把同一个epoll fd的操作都放到同一个线程中执行。
    4. !!!
    POSIX分配文件描述符的方式在不注意的情况下会出现串话,比如说在处理一个连接的请求过程中,另一个线程将这个fd close了,然后又来了新的连接分配了相同的fd,这样处理之前的请求的响应会发错。
    解决办法是RAII,用class去管理fd, 在析构函数中关闭文件描述符,这样的话只要这个class对象还活着,对应的fd就不会close,也就不会串话了。
    当对方客户端断开连接之后,这个tcp connection也即将走到尽头,但这时我们不能马上delete这个对象,因为其他地方可能还持有这个对象,贸然delete可能会造成悬空指针,只有确保其他地方没有持有该对象引用的时候才能安全销毁–>第二条里说的shared_ptr或weak_ptr
    shared_ptr可以保证原fd不会被关闭weak_ptr提升失败也能知道原资源已经销毁
    所以可以用shared_ptr或shared_ptr+weak_ptr管理TcpConnection的生命周期。
    考虑这样的一种情况:
    假如在监听一个fd的EPOLLERR和EPOLLOUT事件,当这个fd的请求在处理过程中,对端关闭了连接,触发EPOLLERR事件然后直接被另一个线程关闭了,但是上一个请求还在处理,这样就会串话。
  4. signalfd函数
  5. 对一个对端已经关闭的socket调用两次write, 第二次将会生成SIGPIPE信号, 该信号默认结束进程.

具体的分析可以结合TCP的”四次握手”关闭. TCP是全双工的信道, 可以看作两条单工信道, TCP连接两端的两个端点各负责一条. 当对端调用close时, 虽然本意是关闭整个两条信道, 但本端只是收到FIN包. 按照TCP协议的语义, 表示对端只是关闭了其所负责的那一条单工信道, 仍然可以继续接收数据. 也就是说, 因为TCP协议的限制, 一个端点无法获知对端的socket是调用了close还是shutdown.

对一个已经收到FIN包的socket调用read方法, 如果接收缓冲已空, 则返回0, 这就是常说的表示连接关闭. 但第一次对其调用write方法时, 如果发送缓冲没问题, 会返回正确写入(发送). 但发送的报文会导致对端发送RST报文, 因为对端的socket已经调用了close, 完全关闭, 既不发送, 也不接收数据. 所以, 第二次调用write方法(假设在收到RST之后), 会生成SIGPIPE信号, 导致进程退出.

为了避免进程退出, 可以捕获SIGPIPE信号, 或者忽略它, 给它设置SIG_IGN信号处理函数
6. 减少mutex临界区的方法:
在加锁之前先准备好一个空的容器,如vector,加锁后用空的vector swap要处理的vector,然后解锁,在临界区外处理swap出来的数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值