3. 多线程
(2)对于 需要写入但不需要等待响应的请求,可以使用 BlockingQueue 完成,例如 log,由一个专门的线程去写入文件,其他线程只需要往 BlockingQueue 写入即可;
(3)线程池大小的阻抗匹配原则
密集计算所占时间的比重为 P,系统一共有 C 个 CPU,线程池大小的经验公式为 T = C/P,P 的估值一般不准确,其最佳值可以上下浮动 50%;
如果 P < 0.2,T 可以取一个固定值,如 5C;
3.1 C++ 系统库线程安全性
(1)内存序:一个线程对某个共享变量的修改何时能被其他线程看到;
(2)C++ 的 iostream 不是线程安全的,可以改用 printf
,保证输出的原子性;
cout << "Now is" << time(NULL);
上面等价下式
cout.operator<<("Now is")
.operator<<(time(NULL));
即便保证了 ostream::operator<<()
是线程安全的,但不能保证其他线程不会在两次函数调用之间向 stdout 输出其他字符;
(3)exit(3)
在 C++ 中不是线程安全的
其除了终止进程,还会析构全局对象和已经构造完的函数静态对象,有潜在死锁可能;
3.2 多线程与 IO
(1)磁盘 IO;每块磁盘都有一个操作队列,多线程磁盘 IO 的一个思路是每个磁盘配一个线程,把所有针对该磁盘的 IO 都挪到同一个线程中,才可能比单线程快;(内核缓存了大部分数据的情况下,多线程也可能更快)
(2)网络 IO;socket 读写的特店是不保证完整性,多线程同时读写可能每个都会收到一部分数据,如何组合这些数据是一个难点;
(3)POSIX 标准要求每次新打开文件(含 socket)的时候必须使用当前最小可用的文件描述符
- 串话
-
一个线程正准备
read
某个 socket,第二个线程几乎同时close
此 socket,第三个线程恰好open
了另一个文件描述符,其号码可能与前面的 socket 相同; -
一个线程从 fd 收到耗时请求,并记住要把处理结果发送给 fd,但在处理过程中,fd 断开了连接,有新的连接到来,碰巧使用了相同的 fd。
-
C++ 中解决串话问题的办法,RAII,用 Socket 对象保证文件描述符,析构时关闭文件描述符;
采用 shared_ptr
管理 TcpConnection 生命期;(只要其他线程持有这个连接的指针其就不会析构,就不会造成串话)
3.3 fork
程序中有 fork
时需要注意,有可能会有对象构造一次,析构了两次
4. Protocol Buffer
4.1 Labels
(1)repeated 修饰
下述方法缺失的部分为变量名;
修饰 message 时,没有 set_
方法
会有 add_
方法_size
修饰标量数值类型时,需要在后面加 [packed = true]
才能高效编码;
(2)optional
如果消息没有包含这个元素,访问其时会返回默认值;[default = 10]
,如果未显式指出默认值,为空值(对枚举类型,为第一个定义的枚举值);
(3)分配 field numbers
每个 field 都需要分配一个数(在该消息中是独一无二的)
为最经常使用的 field 分配 1 ~ 15,越低的数占用空间越少;
被删除的 field numbers 需要添加到保留列表中;
4.2 定义服务
(1)RPC 服务(单词首字母大写)
4.3 zero_copy_stream
尽可能减少内存拷贝,由流对象负责 buffer 申请,返回给调用者一个 buffer,指向最终的数据结构
5. C++ 编译
单遍编译,编译器只能根据目前看到的代码做出决策;
函数重载决议,编译器看到一个函数调用语句时,只能从目前已看到的同名函数中选出最佳函数,哪怕后面代码中出现了更合适的匹配;
(1)C 语言的链接模型
只从前面的章节引用后面的章节,只需一遍遍历即可完成链接;
因此链接时,越基础的库越放到后面;这种做法内存消耗小的多,如果不这样做,先处理基础库,链接器不知道库中哪些符号会被后面的代码用到,只能全部记住;反之,如果先处理应用库,只需记住目前未查到定义的符合即可;
(2)
编译器自动生成的 class 析构函数也是 inline 函数,有时需要显式写一个空的析构函数,防止代码膨胀或出现编译错误(例如使用前向声明和 pimpl 手法,如果是编译器默认析构函数展开时无法看到 Impl 的声明,会报错);文章来源:https://www.toymoban.com/news/detail-807252.html
参考
《Linux 多线程服务端编程》文章来源地址https://www.toymoban.com/news/detail-807252.html
到了这里,关于C++中实现多线程和分布式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!