Linux多线程服务端编程一些总结

时间:2023-03-08 17:50:16

  能接触这本书是因为上一个项目是用c++开发基于Linux的消息服务器,公司没有使用第三方的网络库,卷起袖子就开撸了。个人因为从业经验较短,主 要负责的是业务方面的编码。本着兴趣自己找了这本书。拿到书就简单的翻了下,看到是基于c++11标准的,用到了智能指针、bind/function等 工具。因为对c++11不是很了解再加上表较忙就搁置下来了。现在借着项目的空档期,拜读了陈硕的这本关于服务端多线程开发的书,选取了一些自己比较感兴趣的章节,有些进行了比较深度的阅读,如对象生命期的管理和线程同步、有些则是粗略的浏览了一遍。

  个人觉得读一些书,需要真正的静下心来,这样的效率才能有保证。想获取知识浮躁的心态是要不得的,而且在读书当中应该对重点进行特殊对待。其他的则可以略读或干脆不读。总之一个原则:将精力主要集中在重点知识上去。

  如何在读书的时候把心静下来,暂时还不得要领!需要继续观察总结。在没有更好的方法前只能是先去读书,在读书的过程中达到心静的状态。

1. 多线程编程

  个人认为c++多线程的难点与重点就在

  (1) 共享资源的安全使用

    对象在构造期的线程安全:

      线程A: 在构造期这时如果将对象a注册到另外一个对象b中。 在此时另外一个线程B:对象吧调用方法使用到线程A中注册的对象,这个时候是不能保证对象的完整性的。就算将注册函数的调用放在构造函数的结尾处,还要考虑到这个类是否被继承,如果被继承得到的对象将是不完整的(派生类的对象还没有构造出来)。

      解决方法:将对象的注册放到初始化函数中。不在构造期将对象暴露出去。

    对象在使用中的线程安全:

    要想安全的使用共享资源,就需要用到线程同步的知识。

    线程同步方法:互斥量、条件变量、信号量、读写锁

    书中推荐使用互斥量和条件变量就基本可以解决所有遇到的同步问题,个人也很认同。也就把精力放在了互斥量和条件变量的学习上了。

    对象在析构时的线程安全:
            保证在对象析构时的线程安全是比较麻烦的时,因为在c++中我们没有方法判断对象是否是有效的。通过对对象加锁达不到多线程的安全性,因为在析构的时候对象多持有的锁在析构时就结束了它的生命期。
            书中给出的办法是通过智能指针,当指针的引用计数小于0时对象被析构。
            使用智能指针时需要避开智能指针的一些坑例如循环引用,智能指针不是多线程安全的使用时需要加锁。

  (2) 性能
        这个方面了解的比较少,现在知道的是:
        1) 控制锁的粒度  
        2)线程调度,控制线程的数量,在程序运行中不频繁的创建、销毁线程,安排好线程的职责:专门负责I/O的线程、专门负责计算的线程、第三方库的线程
    
2. 值语义与数据抽象,几个概念
    值语义指的是对象的拷贝与原对象无关,拷贝后与原对象脱离关系。
    与值语义对应的是对象语义或叫引用语义。指的是面向对象意义下的对象,对象拷贝是禁止的。
    数据抽象,用来描述(抽象)数据结构的。
    
    数据抽象、面向对象、基于对象的区别
        面向对象有3大特征:封装、继承、多态。
        而基于对象则只有封装没有继承和多态,即只有具体类没有抽象借口。它们都是对象语义。
        数据抽象是针对“数据“的,这意味着ADT(抽象数据类型)class应该可以拷贝。它是值语义。
    面向对象真正核心思想是消息传递,”封装继承多态“只是表象。具体参考 http://blog.csdn.net/myan/article/details/5928531    function/bind的救赎(上) 作者: 孟岩

参考文章:
    【1】《Linux多线程服务端编程:使用c++muduo网络库》 作者:陈硕