linux C++多线程服务端开发

UNIX

线程安全的对象生命期管理

当析构函数遇到多线程

构造不要在构造函数中注册任何回调

不要在构造函数中把this传给跨线程的对象

即便在构造函数的最后一行也不行,因为这个类可能是基类,构造完基类还要构造派生类,就是怕对象未构造完成,却暴露且使用了this

销毁太难如果线程A对x对象要执行析构,线程B对x要调用update函数,会出问题。

如果用mutex,也不行,比如A获得了互斥锁,进而进行了析构,B虽然阻塞在锁上在等待A释放,但是A已经析构了,B是继续阻塞?天晓得接下来发生什么。

delete之后,把相关变量置为NULL,也是没用的。

作为数据成员的mutex不能保护析构mutexLock可以保证读写正确,但是无法保证析构正确

只有别的线程都访问不到这个对象的时候,析构才安全

如果要同时读这个类的两个对象,有可能发生死锁,比如两个线程分别执行swap(a,b),swap(b,a);

线程安全的Observer有多难一个动态创建的对象是否还或者,光看指针是看不出来的,引用也一样。如果已经销毁就不可能根据里面的状态判断,更不能根据这个指针的值(万一又创建了呢,这种方法是C指针问题的根源)。

简单的方法是只创建不销毁,不够就开辟,用完就放回去。这样至少可疑避免访问失效对象的情况。但是这种山寨方法的问题有:

全局共享数据引发的lockcontention。

对象池的线程安全,如何完全,安全把对象放回去现在要解决的问题是用的时候一定知道对象还活着

要想安全销毁对象,最好在别人(线程)都看不到的情况下,偷偷地做,垃圾回收的原理就是这个

空悬指针

jj

线程同步

线程同步四项原则,按照重要性排列:最低限度共享对象,较少需要同步的场合。

使用高级的并发编程构件

最后使用底层同步原语。使用互斥器和条件变量,慎用读写锁,不要用信号量。

互斥器用RAII手法封装mutex的创建,销毁,加锁,解锁。

只用非递归的mutex

不手工调用lock,unlock,一切交给构造和析构函数

不适用跨进程的mutex,只用tcp sockets

加锁,解锁在同一线程

条件变量

解决互斥锁阻塞的问题

intdequeue(){

lock(mutex);

while(queue.empty())

{

cond.wait();

}

inttop=queue.front();

queue.pop_front();

returntop;

}

voidenqueue(intx){

lock(mutex);

queue.push_back(x);

cond.notify();

}

读写锁

效率不比mutex快。

信号量

条件变量和互斥锁的结合可以替代其功能,而且不易用错。

多线程服务器的适用场合与编程模型多线程可以共享数据,而且更好的利用多核。

单核服务器利用多线程每多少价值

多线程常见模型每个请求创建一个线程,使用阻塞是I/O。

适用线程池,同样使用阻塞IO,与第一种相比,提高了性能。

适用non-blocking IO + IO multiplexing 即,Java NIO

leader/follower 等高级模式

默认情况下是第三种。

one loop per thread

推荐使用one loop per thread + thread pool

进程间通信的方式很多,pipe,FIFO,共享内存,消息队列,还有一些同步原语。

推荐使用TCP,因为如果多进程依然无法满足服务,就需要扩充到其他机器,易于扩展

如果用很少的cpu负载就能让IO跑满,或者用很少的IO流量就可疑让cpu跑满,那么多线程没啥用处。静态web服务器,FTP服务器,cpu的负载很小,主要瓶颈在磁盘IO和网络IO,这时候一个单线程的程序就可疑撑满IO。多线程并不能提高吞吐量。

cpu跑满很少见,比如m个数,找出n个数,使其和为0.,能把cpu算死。这种情况,多启动几个单线程的进程就可疑了。

适合多线程的场景

虽然多线程不能提高绝对性能,但能提高平均响应性能。多核

有数据共享,如果没有数据共享,则用多个进程解决

数据可以修改,如果数据都是敞亮表,就可以在进程间用shared memory,多个进程(每个进程一个线程)

提供非均质的服务,即,时间的相应有优先级差别,可以用专门的线程处理优先级高的

一个好的多线程程序,应该可以享受cpu数目增加带来的好处

32位的机器,4G的地址空间,用户态可以访问3G,如果不修改栈的调用空间10M,300个线程

疑难解答多线程能提高并发度吗?如果指的是并发连接数,则不能。如果单纯采用thread per connection的模型,并发连接数是300,这个远远低于基于事件的单线程程序能轻松到达的并发连接数(几千乃至上完)。基于事件,指的是用IO multiplexing event loop 的编程模型,Reactor。一个multi-loop的多线程程序应该能轻松支持5W。thread不适合高并发的场合。

多线程能提高吞吐量吗?,对于计算密集型服务,不能。

多线程可以降低响应时间吗?可以。如果设计合理,充分利用多核资源的话,可以。

多线程的进程和多个单线程的进程如何取舍。可以根据工作集的大小来取舍。

如果程序有一个较大的cache,几乎每次请求都会访问,多线程会适合,因为这样可以避免每个进程保存一份cache

多线程日志

对于C++程序,最好整个程序使用相同的日志库,程序有一个正体的日志输出,而不要各个组件有各个组件的日志输出。一般的日志风格有两种借助printf();,log_info("");

借助stream<

日志的功能需求

因为日志库不能每条消息都flush到硬盘,也不能每条日志都open/close文件(开销太大)。方法定期(默认3秒)将缓冲区的日志消息flush到硬盘

每条日志消息都带有一个cookie(或者叫哨兵值/sentry),其值是某个函数地址,这样通过coredump文件可疑找到cookie,这样就可以找到尚未写到磁盘的消息。

日志消息格式要点:每条日志占一行。

时间戳精确到微妙。

打印线程id,便于分析多线程的时序,也可以检测死锁。

日志级别。

文件的名字行号。

日志的性能需求

日志库要足够高效。输出足够多的诊断信息,减小运维难度,提升效率。每秒几千上万条日志没有明显的性能损失。

能应对一个进程产生大量日志的场景,比如1GB/min

不阻塞正常的执行流程

在多线程程序中,不造成争用。

性能指标磁盘带宽约110MB/s,日志库应该能瞬间写满这个带宽。

假如每条是110字节,意味着每秒要写100万条

多线程异步日志

用多个buffer,缓冲

muduo网络库简介

linux c++ 线程支持 多核应用,linux C++多线程服务端开发相关推荐

  1. 【云风skynet】详解skynet的多核高并发编程丨actor模型丨游戏开发丨游戏服务端开发丨多线程丨Linux服务器开发丨后端开发

    skynet中多核高并发编程给我们的启发 1. 多核并发编程 2. actor模型详解 3. 手撕一个万人同时在线游戏 视频讲解如下,点击观看: [云风skynet]详解skynet的多核高并发编程丨 ...

  2. 《Linux多线程服务端编程:使用muduo C++网络库》书摘6.6.2节

    6.6.2 常见的并发网络服务程序设计方案 W. Richard Stevens 的<UNIX 网络编程(第2 版)>第27 章"Client-ServerDesign Alte ...

  3. 《Linux多线程服务端编程:使用muduoC++网络库》学习笔记

    文章目录 第1章 线程安全的对象生命期管理 1.1 当析构函数遇到多线程 1.1.1 线程安全的定义 1.1.3 线程安全实例 1.2 对象的创建很简单 1.3 销毁很难 1.4 线程安全的Obser ...

  4. 新书预告:《Linux 多线程服务端编程——使用 muduo C++ 网络库》

    看完了 W. Richard Stevens 的传世经典<UNIX 网络编程>, 能照着例子用 Sockets API 编写 echo 服务, 却仍然对稍微复杂一点的网络编程任务感到无从下 ...

  5. 如何给multicraft装PHP,我的世界Linux搭建Multicraft网页后台教程更新和添加服务端文件...

    小编为大家带来了<我的世界>Linux搭建Multicraft网页后台教程更新和添加服务端文件,这个是一个比较重要的教程,当然用不到的玩家可以跳过了. 重新登录 点击"设置&qu ...

  6. Linux多线程服务端编程学习(四)finger服务的实现

    源码下载以及安装点击链接https://blog.csdn.net/YoungSusie/article/details/90021742 分类 Muduo网络库编程 学习笔记 例 七步实现finge ...

  7. 利用netty开发webScoketClient(支持wss协议,客户端、服务端心跳实现)

    这里写目录标题 前言 题外话 webScoketClient实现方式一(jacva_webscoket) webScoketClient工具类 简单编写测试 webScoketClient实现方式二( ...

  8. linux内核如何支持多核cpu,现在的多核CPU,Linux操作系统是否能够实现单个进程(多线程)的多核调度(跨CPU核心调度)?...

    现在的多核CPU,Linux操作系统是否能够实现单个进程(多线程)的多核调度(跨CPU核心调度)? 关注:106  答案:2  mip版 解决时间 2021-02-02 01:11 提问者你說.你愛我 ...

  9. linux取消线程的原理,浅析 Linux 进程与线程

    简介 进程与线程是所有的程序员都熟知的概念,简单来说进程是一个执行中的程序,而线程是进程中的一条执行路径.进程是操作系统中基本的抽象概念,本文介绍 Linux 中进程和线程的用法以及原理,包括创建.消 ...

最新文章

  1. SimpleTemplate模板引擎开发
  2. Java API帮助文档怎么查找?
  3. 同一个页面同时拥有collectionView和navigationBar和tabBar时可能遇到的问题
  4. eShopOnContainers 是一个基于微服务的.NET Core示例框架
  5. mysql sql wait 写法_有关SQL语句写法注意的那些事情(原创整理)
  6. Java校招笔试题-Java基础部分(二)
  7. Java枚举(用Java普通类模拟枚举的实现原理及JDK枚举API使用示例)
  8. DJ音乐播放管理软件rekordbox如何从导出设备恢复音乐
  9. C# 网络爬虫 抓取“北京标准时间“ 网页请求
  10. OpenLayers教程十五:多源数据加载之矢量地图
  11. 2020年岁末的年终总结——来自一位70后的大龄程序员的总结分享
  12. 竞争型神经网络:自组织映射神经网络(SOM)
  13. 偏导数,全导数,方向导数,偏微分,全微分,梯度
  14. PIO(编程输入/输出模型)和DAM(直接访问内存)
  15. Android最新API获取北斗卫星定位信息(全网最新)
  16. 陆面生态水文模拟与多源遥感数据同化与Noah-MP模型
  17. android长按home键流程
  18. 容性耦合等离子体(CCP)和电感耦合等离子体(ICP)
  19. OSChina 周二乱弹 ——人和人之间的关系用通话时间来表述
  20. 同态加密在联邦计算中的应用

热门文章

  1. win10 声音设置
  2. 优秀网页设计的七条基本准则
  3. 美妆科技:改变美容行业的未来
  4. LiveData原理解析
  5. android字符串加删除线,android textview 添加上划线 中划线 删除线
  6. python视频教程哪个好-Python 基础视频教程那个好?
  7. 知识计算机硬件 教学设计,计算机硬件教案
  8. UBR/CBR/VBR
  9. 百度搜索结果页url参数详解
  10. 计算机的基础知识(一)