这篇笔记只是记录了书中的一些思路,和网络服务器需要些什么东西,并没有去深入研究代码。比如说第五章的日志系统,日志系统需要哪些功能,需要注意什么地方,记载的是这类东西。
第一章 线程安全的对象声明周期管理
1.不要在对象构造函数 或 析构函数中出现this指针、注册回调、把this指针传递给跨线程对象。因为只要还在构造函数,对象就不是一个被构造好的对象,只要进入析构函数,对象就不是一个完整的对象。在多线程中使用未构造好的对象和已经销毁的对象是不安全的。
2.二段式构造。书中提出多线程情况下用构造函数+init()函数来构造对象,把注册回调这类危险的操作放在init()中,通过init()的返回值来判断对象是否构造成功。
3.作为数据成员的mutex不能保护析构函数。
4.C++中出现内存问题的几个方面。①缓冲区溢出②野指针③重复释放④内存泄漏⑤不配对的 new[] / delete⑥内存碎片。
其中缓冲区溢出可以通过自定义缓冲区类来避免,内存碎片可以通过内存池来解决,其余的都可通过智能指针来解决。
5.智能指针share_ptr本身是线程安全的,但其所指的对象不是。
智能指针的引用计数在哪个线程为0,就在哪个线程析构,如果析构比较耗时,可能会拖延线程进度。
第二章 线程同步
这一章主要讲了些线程同步的东西,在link。写写书上的线程同步原则。
1.尽量最低限度共享对象
2.略
3.只用非递归mutex和条件变量,慎用读写锁,不用信号量
4.不自己编写lock-free,这里大概指的是使用《C++并发编程实战》中内存顺序那一块的东西。
第三章 多线程服务器适应场景和常用编程模型
这一章看的时候勾勾画画的东西也不少,但是一写笔记就感觉好像也没什么可写的。
进程间通信只用TCP
1.首先TCP通信可以跨主机,其他进程间通信都做不到。
2.TCP是双向的,Linux的管道是单向的,还限制在有父子关系进程的情况下。
3.TCP独占端口,且操作系统会在进程结束时自动回收,还可以防止重复启动。
4.如果连接中断,TCP可以立即发现。
5.调试方便,可借助tcpdump或者wireshark。
6.可重新连接,当一个进程死掉,只需重启这一个进程重新连接即可。
一个对框架模糊的理解
大概就是reactor了,一个线程来等待客户端的连接,其他多个线程来处理,分细一点,专门的线程recv,专门的线程send,专门的线程来进行计算。还有一些其他的辅助线程如日志之类的。
第四章 线程
这一章大概写了多线程碰上信号、fork之类的应该如何,这些东西在unp.中有写到,但是最好的方法就是避免这些情况。
第五章 日志
1.日志的文件名应该由:机器名称、进程名字、进程ID、文件创建时间(或者说第一条消息的时间)、后缀.log
2.一条日志的消息应该包含 全局消息ID、日期、时间(精确到微秒)、线程、级别、【甚至是在哪个文件在哪一行、】消息内容 内部状态变更等一些详细信息。
关于时间戳在linux中通过gettimeofday()来获取,这不是系统调用,不会陷入内核。
3.日志消息应该有多种级别:DEBUG、INFO、WARN、ERROR、FATAL
4.日志系统不应该重复利用空间,当发生死循环拼命写日志的情况,往往是最开始几条日志信息有用,所以不应该重复利用空间覆盖先前的日志。
5.如果程序崩溃,往往最后几条最重要的消息可能因为没有及时同步导致丢失,每条消息带有哨兵值(没理解书中哨兵值,大概是全局消息ID?),在程序崩溃后通过core文件来找到没有及时写入的日志。
2020年8月31日22:31:59 1,2,3,4,5章