C++开发精髓 阅读笔记

2023-05-16

第三章

pstack的使用

将C++类对象实例指针作为线程函数的参数

bind函数

auto newCallable = bind(callable,arg_list);

我们调用newCallable时,newCallable会调用callable,并传给它arg_list中的参数。

假设我们将线程的基本功能都封装到一个Theard类中

class Thread{
	void* threadFunc(void* arg);
};

threadFunc作为类的非静态方法,被编译后第一个参数会变成this指针 不符合线程函数的签名要求了

如果使用std::thread类,可以使用非静态方法作为线程函数。但必须还要传入this指针 也可以使用bind

以下是线程类的示例

class Thread{
public:
    Thread(){};
    ~Thread(){};
    void Start(){
        m_stop = false;
        // 线程函数是类的非静态方法
        // 作为线程函数 第一个参数必须传递类实例的地址
       // m_spthread.reset(new std::thread(&Thread::ThreadFunc, this, 8888));
        m_spthread.reset(new std::thread(std::bind(&Thread::ThreadFunc, this, 8888)));

    }
    void Stop(){
        m_stop = true;
    }
private:
    void ThreadFunc(int a){
        while(!m_stop){
            sleep(1);
            printf("d\n");
        }
    }
private:
    std::shared_ptr<std::thread> m_spthread;
    bool m_stop;
};
std::atomic_int value = 99;
// 在linux平台上将会报错 因为g++ 使用delete禁止std::atomic默认生成拷贝构造函数

互斥体

锁类型:
普通锁 对已加锁的对象再次加锁 会阻塞 (try_lock不会)
检错锁 一个线程对互斥体对象再次加锁,返回EDEADLK ,若是一个线程对某个互斥体加锁,另一个线程再次对其加锁,会阻塞。
可重入锁

条件变量

为什么需要条件变量?

如果我们需要判断一个多线程的共享条件是否满足,每次判断都要加锁和解锁,我们需要这样一种机制: 在条件不满足的情况下主动让出互斥体,一旦条件满足,可以被立刻唤醒。

为什么条件变量一定要和互斥体共享使用?

// 线程A
1: pthread_mutex_lock(&mutex);
2: while (false == ready) {
3:     pthread_cond_wait(&cond, &mutex);
4: }
	// 条件满足 执行程序
5: pthread_mutex_unlock(&mutex);
// 线程B
1: ready = true;
2: pthread_cond_signal(&cond);

如果在 ready = false 的时候,Thread A 进入 while 循环,但是还没有执行 wait 的时候,thread B 执行了 ready = true 和 signal 唤醒,那么就出现条件变量唤醒 signal 先于 wait,那么相当于 Thread A 还没有被加入唤醒队列,这个时候,你已经 signal 唤醒了,那么这次唤醒自然就丢失了

问题就在于要确保检测条件和将线程挂入等待队列这两个操作是原子性的。

条件变量的虚假唤醒:

        while(tasks.empty()){
            pthread_cond_wait(&mycv, &mymutex);
        }

为什么要在条件变量醒来之后再次判断条件是否满足?
因为操作系统可能在某些情况下唤醒条件变量,这被称为虚假唤醒
底层原因:
当系统调用被信号中断时,会返回 - 1,并把errno设置为EINTR,很多这种系统调用被中断后都会再调用一次这个函数,但是cond_wait不能这么做,因为再调用的过程中可能错失信号,所以宁可虚假唤醒,也不能再次调用,以免陷入无穷等待中。

读写锁

第四章 网络编程

TCP通信基本流程

建立连接
TCP客户端
socket()
connect()
send()
recv()
close()
TCP服务端
socket()
bind()
listen()
accept()
recv()
send()
recv()
close()

bind函数

服务端bind函数如何选择绑定地址?

bindaddr.sin_addr.s_addr = htonl(INADDR_ANY);相当于0.0.0.0
如果我们不关心绑定的IP地址,底层协议栈会自动选择一个合适的IP地址。

客户端也可以使用bind函数选择绑定到某一个端口(0和不绑定的效果是一样的)

select函数

fd_set结构类型是一个 1024bit的数组。

long int __fds_bits[16]; // 16 * 8 * 8

使用位图法来表示状态,因此select支持的最大fd就是1024;

select使用注意事项:

  1. select在调用前后可能会修改readfds,writefds,exceptfds这三个集合中的内容。所以每次重新调用select的时候需要清空set再添加。
  2. 超时时间也需要重新设置。
  3. 超时时间若被设置为0,select将立刻返回。设置为NULL,将一直阻塞,直到事件触发。
  4. 在Linux上,select必须设置为需要检测fd的最大值+1;
  5. select的缺点如下
    • 每次调用都需要把fd集合从用户态复制到内核态
    • 单个进程能够监视的文件描述符存在最大限制
    • 需要重新设定集合参数
    • linux上select底层原理是使用了poll函数

socket阻塞和非阻塞模式

阻塞:条件不满足时阻塞当时线程
非阻塞:条件不满足时立即返回 执行程序流

send 与 recv

send函数在本质上并不是向网络上发送数据,而是将应用层发送缓冲区的数据拷贝到内核缓冲区中,至于数据什么时候会从网卡缓冲区中真正地发送到网络中,要根据TCP/IP协议栈的行为来定,如果socket禁用了nagel算法,存放到内核缓冲区中的数据就会被立刻发出去,否则会将多个小的数据包凑成一个足够大的才发出去。
recv函数是将内核缓冲区中的数据拷贝到应用程序的缓冲区中,拷贝完成后会将内核缓冲区中的数据移除。

第五章 常见网络调试命令

ifconfig

ping

telnet 交互式访问

netstat 查看网络连接

查看连接某ip地址端口最多的ip地址

 netstat -nat | grep "10.206.0.13:22" | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -nr | head -3

lsof 列出当前系统打开文件

查询1883端口状态
sudo lsof -i | grep 1883

可以用来恢复一些文件

nc netcat

curl 模拟HTTP请求

指定请求方法
curl -x POST -d 'data' 'www.baidu.com'

tcpdump

网络通信协议设计

TCP是流式协议,内容与内容之间没有明确的分界标志,需要人为给这些内容划分边界。

如何解决粘包问题?

TCP通过序列号和包重传机制保证数据包的有序和被正确发送到目的地。
只需要解决如何粘包的问题。
解决方法: 固定包长 以指定的字符串结尾的结束标志 包头或者是包体

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++开发精髓 阅读笔记 的相关文章

  • 1.karto-slam涉及的类-雷达以及雷达数据相关

    首先是最简单的 1 sensor msgs LaserScan 主要包括header 还有激光参数 xff08 扫射范围距离 xff0c 步长 xff0c 时间等 xff0c 不包含位姿信息 xff0c header里面含有frame id
  • catkin build 和 catkin_make

    首先安装 xff1a sudo apt get install python catkin tools 编译过程中你可能会遇到以下错误 xff0c 那是因为以前使用了catkin make进行编译 xff0c 需要把build和devel删
  • 使用Haar特征进行人脸识别

    这篇博客对2001年那篇划时代的paper xff1a Rapid Objection Using a Boosted Cascade of Simple Features进行一个简要的解析 这篇文章之后人脸识别的效果有了很大的提升 后来还
  • MySQL基础课程三件套,年前轻松带你带你入门数据库管理系统~

    今天已经2022年1月11日了 xff0c 相信大部分的宝子们已经进入快乐的寒假了 xff0c 今天给对数据库感兴趣的童鞋们推荐B站上的一系列数据库管理入门课 该系列课程分为三个部分 xff0c 第一部分为MySQL新手入门教程详解 xff
  • 【kazam】linux下截屏、录屏软件kazam的简单使用

    安装 xff1a sudo apt get install kazam 或者使用 ppa 安装 sudo add apt repository ppa kazam stable series sudo apt get update sudo
  • LCD24064显示程序,此工程直接运行。

    T6963C C51 Source Code240X64MCU W78E516D 12MHZLCM Controller T6963C RA6963 24064A B 1 FG GND 2 GND GND
  • 四旋翼无人机飞行器基本知识(四旋翼无人机结构和原理+四轴飞行diy全套入门教程)

    第一篇 四旋翼飞行器结构和原理 第二篇 四旋翼飞行diy全套入门教程 四旋翼飞行器结构和原理 1 结构形式 旋翼对称分布在机体的前后 左右四个方向 xff0c 四个旋翼处于同一高度平面 xff0c 且四个旋翼的结构和半径都相同 xff0c
  • 四旋翼飞控原理

    以前 xff0c 搞无人机的十个人有八个是航空 气动 机械出身 xff0c 更多考虑的是如何让飞机稳定飞起来 飞得更快 飞得更高 如今 xff0c 随着芯片 人工智能 大数据技术的发展 xff0c 无人机开始了智能化 终端化 集群化的趋势
  • 四旋翼飞控原理

    以前 xff0c 搞无人机的十个人有八个是航空 气动 机械出身 xff0c 更多考虑的是如何让飞机稳定飞起来 飞得更快 飞得更高 如今 xff0c 随着芯片 人工智能 大数据技术的发展 xff0c 无人机开始了智能化 终端化 集群化的趋势
  • 四旋翼飞行器控制原理与设计

    一 相关理论知识 1 坐标系与欧拉角 进行动力学建模之前首先建立坐标系 xff0c 在此建立地球坐标系和机体坐标系 xff0c 如图所示 xff0c 这里地球系z轴方向向下指向地心 xff0c 机体系x轴为机头方向 当描述一个三维空间内的刚
  • kalman 滤波

    卡尔曼 Kalman 滤波算法原理 C语言实现及实际应用 文章目录 卡尔曼滤波 一 滤波效果展示 二 简介 三 组成 预测状态方程 xff08 1 xff09 目的 xff1a xff08 2 xff09 方程 xff1a xff08 3
  • 软件项目管理 7.4.3.进度计划编排-时间压缩法

    公众号 64 项目管理研究所 将会第一时间更新文章并分享 行业分析报告 归档于软件项目管理初级学习路线 第七章 软件项目进度计划 该文章图片解析有问题 xff0c 点击此处查看 xff01 这里 xff01 前言 大家好 xff0c 这节我
  • maven解析依赖报错:Cannot resolve com.baomidou:mybatis-plus-generator:3.4.2

    不能解析依赖 xff1a span class token tag span class token tag span class token punctuation lt span dependency span span class t
  • 客户要求压缩进度,项目经理怎么办?

    几乎每个项目经理都会遇到这样的客户 xff1a 客户 xff1a 王经理 xff0c 我们现在这个项目 xff0c 上头领导说了 xff0c 原定在11月中旬上线的日期 xff0c 需要提前到十一国庆节前上线 xff0c 业务部门需要这个系
  • 树莓派关机重启命令

    关机方法任选一行即可 1 2 3 4 sudo shutdown h now sudo halt sudo poweroff sudo init 0 重启方
  • OpenCV实现车牌定位和字符分割

    前言 xff1a 本案例的车牌图像来源于互联网 xff0c 如有侵权请尽快联系我 xff0c 立删 文章目录 一 概述二 车牌图像分析三 车牌定位1 基本处理2 图像降噪3 灰度拉伸4 图像差分5 二值化6 边缘检测7 形态学处理8 定位车
  • 对四旋翼无人机飞行的认识(飞行控制原理)

    四旋翼无人机的对称组成结构 所以有两种飞行姿态 xff0c 一种是根据四旋翼十字对称的结构 xff0c 将处于同一水平线的一对机架梁作为x轴 xff0c 另一对梁作为y轴的 43 型飞行姿态 xff1b 另一种是将相应两个梁的对称轴线作为x
  • 嵌入式linux学习笔记:01_开发环境及linux基本命令

    开发环境 一 嵌入式技术分析1 嵌入式开发系统 gt linux2 编程语言 gt C语言3 嵌入式开发平台 xff1a GEC6818 平台 二 安装嵌入式开发环境 xff1f 1 什么是虚拟机vmware xff1f 2 为什么要安装虚
  • Ubuntu笔记——apt指令

    2020 10 28 星期三 Ubuntu笔记 apt options command package options xff1a 可选 h xff08 帮助 xff09 xff0c y xff08 当安装过程提示选择全部为 34 yes
  • python plt.plot bar 设置绘图尺寸大小

    plt span class token punctuation span rcParams span class token punctuation span span class token string 39 figure figsi

随机推荐