做静态页面的网站/整站seo排名费用价格

做静态页面的网站,整站seo排名费用价格,网站需求分析怎么写,网站建设的风险重点内容 视频讲解:《CLinux编程进阶:从0实现muduo C网络框架系列》-第6讲.C死锁问题如何分析调试-原子操作,互斥量,条件变量的封装 代码改动 lesson6代码 实现:base/Atomic.h 实现:base/Mutex.h 实现:base/Condit…

重点内容

视频讲解:《C++Linux编程进阶:从0实现muduo C++网络框架系列》-第6讲.C++死锁问题如何分析调试-原子操作,互斥量,条件变量的封装

代码改动

lesson6代码

  • 实现:base/Atomic.h

  • 实现:base/Mutex.h

  • 实现:base/Condition.h/cc

  • examples/test_atomic_mutex.cc

1 AtomicIntegerT原子操作封装

1.1 封装意义

目的是更符号项目的用法,用起来更得心应手。

这种封装在网络库中特别有用,因为网络库经常需要处理并发场景,比如:

  • 统计连接数

  • 管理连接状态

  • 处理引用计数

  • 实现无锁队列

  • 实现线程安全的计数器

1.2 类图

AtomicIntegerT<T>
├── 私有成员
│   └── volatile T value_
├── 构造/析构
│   ├── AtomicIntegerT()	// 默认构造函数,初始值为0
│   └── explicit AtomicIntegerT(T x)	// 构造函数,禁止隐式类型转换
├── 原子读取操作
│   └── T get() // 原子性地读取value_的值
├── 原子修改操作
│   ├── T getAndSet(T newValue) // 原子性地将value_设置为newValue,并返回之前的值
│   ├── T getAndAdd(T x)// 原子性地将value_加上x,并返回之前的值
│   ├── T addAndGet(T x)// 原子性地将value_加上x,并返回新的值
│   ├── T incrementAndGet()	// 原子性地将value_加1,并返回之前的值
│   └── T decrementAndGet()	// 原子性地将value_减1,并返回之前的值
└── 便捷操作├── void add(T x)	// 原子性地将value_加上x├── void increment()	// 原子性地将value_加1└── void decrement()	// 原子性地将value_减1

使用typedef 定义了AtomicInt32 AtomicInt64

// 定义32位和64位原子整数类型
typedef detail::AtomicIntegerT<int32_t> AtomicInt32;
typedef detail::AtomicIntegerT<int64_t> AtomicInt64;

1.3 原子操作实现原理

  • 使用GCC内置的原子操作函数:

__sync_val_compare_and_swap  // CAS操作
__sync_lock_test_and_set     // 原子交换
__sync_fetch_and_add         // 原子加法// 原子性地读取value_的值
T get()
{return __sync_val_compare_and_swap(&value_, 0, 0);
}// 原子性地将value_设置为newValue,并返回之前的值
T getAndSet(T newValue)
{return __sync_lock_test_and_set(&value_, newValue);
}// 原子性地将value_加上x,并返回之前的值
T getAndAdd(T x)
{return __sync_fetch_and_add(&value_, x);
}
  • 这些函数在编译时会被转换为CPU的原子指令

  • 比如x86平台会使用lock前缀的指令

1.4 在muduo中的使用场景

class Thread : noncopyable
{static AtomicInt32 numCreated_;  //静态变量,用来计算创建的线程序号
};void Thread::setDefaultName()
{int num = numCreated_.incrementAndGet();   //创建的线程序号if (name_.empty()){char buf[32];snprintf(buf, sizeof buf, "Thread%d", num);  //设置唯一的线程名字name_ = buf;}
}
class TcpServer {AtomicInt32 started_;  // 标记服务是否启动
};void TcpServer::start()
{if (started_.getAndSet(1) == 0)  // 默认值是0,获取之前的值并设置新值,避免程序二次启动{threadPool_->start(threadInitCallback_);assert(!acceptor_->listening());loop_->runInLoop(std::bind(&Acceptor::listen, get_pointer(acceptor_)));}
}
class Timer : noncopyable
{static AtomicInt64 s_numCreated_; //创建的定时器序号Timer(TimerCallback cb, Timestamp when, double interval): callback_(std::move(cb)),expiration_(when),interval_(interval),repeat_(interval > 0.0),sequence_(s_numCreated_.incrementAndGet())  //当前定时器的序号{ }
}

1.5 使用示例

// 测试原子操作
void testAtomic()
{printf("Testing Atomic operations...\n");AtomicInt32 a0;assert(a0.get() == 0);assert(a0.getAndAdd(1) == 0);assert(a0.get() == 1);assert(a0.addAndGet(2) == 3);assert(a0.get() == 3);assert(a0.incrementAndGet() == 4);assert(a0.get() == 4);assert(a0.decrementAndGet() == 3);assert(a0.get() == 3);printf("Atomic test passed!\n");
}

2 MutexLock/MutexLockGuard互斥量封装

2.1 封装意义

  • 提供RAII风格的互斥锁管理

  • 追踪锁的持有者,方便调试

  • 防止误用和死锁

2.2 类图

MutexLock
├── 私有成员
│   ├── pthread_mutex_t mutex_
│   └── pid_t holder_
├── 构造/析构
│   ├── MutexLock()
│   └── ~MutexLock()
├── 锁操作
│   ├── void lock()
│   └── void unlock()
├── 调试功能
│   ├── bool isLockedByThisThread()
│   └── void assertLocked()
└── 友元类└── ConditionMutexLockGuard
├── 私有成员
│   └── MutexLock& mutex_
├── 构造/析构
│   ├── MutexLockGuard(MutexLock& mutex)
│   └── ~MutexLockGuard()
└── 禁止拷贝└── noncopyable

2.3 实现原理

  • 使用pthread_mutex作为底层实现

  • 通过RAII自动管理锁的获取和释放

  • 通过gettid()追踪锁的持有者

2.4 在muduo中的使用场景

使用的场景较多,这里只展示了在EventLoop,ThreadPool中的使用。

void EventLoop::queueInLoop(Functor cb)
{{MutexLockGuard lock(mutex_);  //加锁pendingFunctors_.push_back(std::move(cb));}if (!isInLoopThread() || callingPendingFunctors_){wakeup();}
}
size_t ThreadPool::queueSize() const
{MutexLockGuard lock(mutex_);   //加锁return queue_.size();
}

2.4 使用示例

muduo库封装的Mutex功能很多,但我们目前知道调用

MutexLockGuard lock(mutex);  加锁就行,其他的用法不做要求。

isLockedByThisThread 是一个用于调试和断言的重要函数,让我详细解释它的使用:

1.基本用法(掌握这里就行)

MutexLock mutex;
{MutexLockGuard lock(mutex);
}

2.常见使用场景(不做要求)

class ThreadSafeClass {
public:void method1() {MutexLockGuard lock(mutex_);// 确保在持有锁的情况下调用method2method2();  // 内部方法调用}private:void method2() {// 确保调用此方法时已经持有锁mutex_.assertLocked();  // 如果未持有锁,会触发断言// 执行操作...}MutexLock mutex_;
};

3.调试死锁(不做要求)

class Resource {
public:void access() {MutexLockGuard lock(mutex_);// 检查是否真的持有锁if (!mutex_.isLockedByThisThread()) {printf("Warning: Lock not held by current thread!\n");}// 执行操作...}private:MutexLock mutex_;
};

4.防止误用(不做要求)

class SafeCounter {
public:void increment() {// 确保在持有锁的情况下修改数据if (!mutex_.isLockedByThisThread()) {printf("Error: Must hold lock to modify counter!\n");return;}count_++;}private:MutexLock mutex_;int count_;
};

5.实际应用示例(不做要求)

class ThreadSafeQueue {
public:void push(int value) {MutexLockGuard lock(mutex_);// 确保在持有锁的情况下调用内部方法doPush(value);}private:void doPush(int value) {// 确保调用此方法时已经持有锁mutex_.assertLocked();queue_.push(value);}MutexLock mutex_;std::queue<int> queue_;
};

3 Condition条件变量的封装

3.1 封装意义

  • 提供线程间的同步机制

  • 实现生产者-消费者模式

  • 支持超时等待功能

  • 与MutexLock配合使用,确保线程安全

3.2 类图

Condition
├── 私有成员
│   ├── MutexLock& mutex_      // 互斥锁引用
│   └── pthread_cond_t pcond_  // 条件变量
├── 构造/析构
│   ├── explicit Condition(MutexLock& mutex)
│   └── ~Condition()
├── 等待操作
│   ├── void wait()           // 等待通知
│   └── bool waitForSeconds(double seconds)  // 超时等待
└── 通知操作├── void notify()         // 通知一个等待线程└── void notifyAll()      // 通知所有等待线程

3.3 实现原理

本质是调用pthread线程库的接口 以及封装的MutexLock。

class Condition : noncopyable....MutexLock& mutex_;        // 互斥锁引用pthread_cond_t pcond_;    // 条件变量
};

3.4 在muduo中的使用场景

用于ThreadPool任务队列的生产者-消费者模型。

用于EventLoopThread等等IO Loop线程创建成功。

class ThreadPool : noncopyable
{mutable MutexLock mutex_;Condition notEmpty_ GUARDED_BY(mutex_);Condition notFull_ GUARDED_BY(mutex_);  //用来处理任务队列(生产者消费者模式)
}
EventLoop* EventLoopThread::startLoop()
{assert(!thread_.started());thread_.start();EventLoop* loop = NULL;{MutexLockGuard lock(mutex_);while (loop_ == NULL){cond_.wait();    //等等loop线程创建成功}loop = loop_;}return loop;
}void EventLoopThread::threadFunc()
{EventLoop loop;if (callback_){callback_(&loop);}{MutexLockGuard lock(mutex_);loop_ = &loop;cond_.notify();  //发通知,io loop线程已经准备好了}loop.loop();//assert(exiting_);MutexLockGuard lock(mutex_);loop_ = NULL;
}

使用示例

// 生产者-消费者模式
class Buffer {
public:Buffer(int size) : size_(size), notEmpty_(mutex_), notFull_(mutex_) {}void put(int item) {MutexLockGuard lock(mutex_);while (queue_.size() == size_) {notFull_.wait();  // 等待队列不满}queue_.push(item);notEmpty_.notify();  // 通知消费者}int get() {MutexLockGuard lock(mutex_);while (queue_.empty()) {notEmpty_.wait();  // 等待队列不空}int item = queue_.front();queue_.pop();notFull_.notify();  // 通知生产者return item;}private:MutexLock mutex_;Condition notEmpty_;Condition notFull_;std::queue<int> queue_;int size_;
};

关键特性

  • 与MutexLock配合使用

  • 支持超时等待

  • 提供广播通知

  • 自动管理锁的释放和获取

使用建议

  • 总是与MutexLock配合使用

  • 使用while循环检查条件

  • 注意通知的时机

  • 合理使用notify和notifyAll

  • 考虑使用超时机制避免死锁

这种封装在网络库中特别有用,因为:

  • 需要处理异步事件

  • 需要实现任务队列

  • 需要处理定时器

  • 需要实现线程池

  • 需要处理生产者-消费者模式

4 完整的测试范例

完整测试代码:examples/test_atomic_mutex.cc

4.1 测试框架图

test_atomic_mutex.cc
├── 基础功能测试
│   ├── testAtomic()     // 原子操作测试
│   └── testMutex()      // 互斥锁测试
└── 条件变量测试└── testCondition()  // 生产者-消费者模式测试├── Buffer类├── producer线程└── consumer线程

4.2 原子操作测试流程图

testAtomic()
├── 初始化测试
│   └── AtomicInt32 a0
├── 基本操作测试
│   ├── get() == 0
│   ├── getAndAdd(1) == 0
│   └── get() == 1
├── 复合操作测试
│   ├── addAndGet(2) == 3
│   └── get() == 3
└── 自增自减测试├── incrementAndGet() == 4├── get() == 4├── decrementAndGet() == 3└── get() == 3

4.3 互斥锁测试流程图

testMutex()
├── 创建互斥锁
│   └── MutexLock mutex
├── 加锁测试
│   ├── MutexLockGuard lock(mutex)
│   └── assert(mutex.isLockedByThisThread())
└── 解锁测试└── 作用域结束自动解锁

4.4 生产者-消费者模式原理图

[生产者线程1]     [生产者线程2]↓               ↓└──────┐    ┌──┘↓    ↓[Buffer缓冲区]↓    ↓┌──────┘    └──┐↓               ↓
[消费者线程1]  [消费者线程2]  [消费者线程3]

4.5 Buffer类结构图

Buffer类
├── 私有成员
│   ├── size_t size_           // 缓冲区大小
│   ├── MutexLock mutex_       // 互斥锁
│   ├── Condition notEmpty_    // 不空条件变量
│   ├── Condition notFull_     // 不满条件变量
│   └── std::queue<int> queue_ // 数据队列
└── 公共方法├── put(int item)          // 生产者方法└── get()                  // 消费者方法

4.6 线程同步流程图

4.6 测试输出

具体看代码打印

lesson6/build$ ./bin/test_atomic_mutex

5 章节总结

重点:

  • 原子封装的目的是提供对于项目更易用的接口,并大致了解下

  • gcc原子操作相关的函数,比如__sync_fetch_and_add

  • 了解Atomic MutexLock和Condition等封装在muduo网络库的使用。

  • 掌握MutexLock类里保存获得锁的线程ID的作用,这样更方便分析死锁问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/73847.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

matplotlib标题比x,y轴字体大,明明标题字体更大?

原始代码&#xff1a; plt.xlabel(训练轮次&#xff08;Epochs&#xff09;, fontsize14, fontweightbold, fontpropertieschinese_font) # 设置中文字体、加大、加粗 plt.ylabel(R值, fontsize14, fontweightbold, fontpropertieschinese_font) # 设置中文字体、加大、加粗…

Baklib内容中台的核心优势是什么?

智能化知识管理引擎 Baklib的智能化知识管理引擎通过多源数据整合与智能分类技术&#xff0c;实现企业知识资产的自动化归集与动态更新。系统内置的语义分析算法可自动识别文档主题&#xff0c;结合自然语言处理技术生成结构化标签体系&#xff0c;大幅降低人工标注成本。针对…

vscode 通过Remote-ssh远程连接服务器报错 could not establish connection to ubuntu

vscode 通过Remote-ssh插件远程连接服务器报错 could not establish connection to ubuntu&#xff0c;并且出现下面的错误打印&#xff1a; [21:00:57.307] Log Level: 2 [21:00:57.350] SSH Resolver called for "ssh-remoteubuntu", attempt 1 [21:00:57.359] r…

飞书电子表格自建应用

背景 coze官方的插件不支持更多的飞书电子表格操作&#xff0c;因为需要自建应用 飞书创建文件夹 创建应用 开发者后台 - 飞书开放平台 添加机器人 添加权限 创建群 添加刚刚创建的机器人到群里 文件夹邀请群 创建好后&#xff0c;就可以拿到id和key 参考教程&#xff1a; 创…

LangFlow系列:LangFlow快速入门示例

本文介绍了开源AI开发工具LangFlow的快速入门方法。LangFlow作为可视化框架&#xff0c;支持通过拖拽组件构建多智能体及RAG应用&#xff0c;兼容主流大语言模型与向量数据库。文章从环境搭建、核心功能到实战案例逐步讲解&#xff0c;演示如何利用其可视化界面创建智能聊天机器…

基于龙芯3A5000处理器,全国产标准6U VPX板卡解决方案

1&#xff0c;产品功能 本产品为一款高可靠性的基于龙芯3A5000处理器以及 7A2000芯片组的标准6U VPX板卡&#xff0c;具有以太网、SATA、PCIE&#xff0c;以及显示等接口&#xff0c;产品功能框图如图1所示&#xff1a; 图1 系统框图 2&#xff0c;技术指标 序号 项目 指标…

无人机进行航空数据收集对于分析道路状况非常有用-使用无人机勘测高速公路而不阻碍交通-

无人机进行航空数据收集对于分析道路状况非常有用-使用无人机勘测高速公路而不阻碍交通- 瑞士拥有1,400 多公里长的高速公路网络。这些公路将人和货物从山谷高原运送到阿尔卑斯山的最高山口。维护这些高速公路使国家得以顺利运转。高速公路维护的重要性显而易见&#xff0c;但在…

推荐系统(十七):在TensorFlow中用户特征和商品特征是如何Embedding的?

在前面几篇关于推荐模型的文章中&#xff0c;笔者均给出了示例代码&#xff0c;有读者反馈——想知道在 TensorFlow 中用户特征和商品特征是如何 Embedding 的&#xff1f;因此&#xff0c;笔者特意写作此文加以解答。 1. 何为 Embedding &#xff1f; 关于 Embedding&#x…

关于ArcGIS中加载影像数据,符号系统中渲染参数的解析

今天遇到一个很有意思的问题&#xff0c;故记录下来&#xff0c;以作参考和后续的研究。欢迎随时沟通交流。如果表达错误或误导&#xff0c;请各位指正。 正文 当我们拿到一幅成果影像数据的时候&#xff0c;在不同的GIS软件中会有不同效果呈现&#xff0c;但这其实是影像是…

CANoe入门——CANoe的诊断模块,调用CAPL进行uds诊断

目录 一、诊断窗口介绍 二、诊断数据库文件管理 三、添加基础诊断描述文件&#xff08;若没有CDD/ODX/PDX文件&#xff09;并使用对应的诊断功能进行UDS诊断 3.1、添加基础诊断描述文件 3.2、基于基础诊断&#xff0c;使用诊断控制台进行UDS诊断 3.2.1、生成基础诊断 3.…

【数据结构】二叉树的递归

数据结构系列三&#xff1a;二叉树(二) 一、递归的原理 1.全访问 2.主角 3.返回值 4.执等 二、递归的化关系思路 三、递归的方法设计 一、递归的原理 1.全访问 方法里调用方法自己&#xff0c;就会形成调用方法本身的一层一层全新相同的调用&#xff0c;方法的形参设置…

【LVS】负载均衡群集部署(DR模式)

部署前IP分配 DR服务器&#xff1a;192.168.166.101 vip&#xff1a;192.168.166.100 Web服务器1&#xff1a;192.168.166.104 vip&#xff1a;192.168.166.100 Web服务器2&#xff1a;192.168.166.107 vip&#xff1a;192.168.166.100 NFS服务器&#xff1a;192.168.166.108 …

C++Primer学习(14.1 基本概念)

当运算符作用于类类型的运算对象时&#xff0c;可以通过运算符重载重新定义该运算符的含义。明智地使用运算符重载能令我们的程序更易于编写和阅读。举个例子&#xff0c;因为在Sales_item类中定义了输入、输出和加法运算符&#xff0c;所以可以通过下述形式输出两个Sales_item…

计算机视觉准备八股中

一边记录一边看&#xff0c;这段实习跑路之前运行完3DGAN&#xff0c;弄完润了&#xff0c;现在开始记忆八股 1.CLIP模型的主要创新点&#xff1a; 图像和文本两种不同模态数据之间的深度融合、对比学习、自监督学习 2.等效步长是每一步操作步长的乘积 3.卷积层计算输入输出…

基于大语言模型的智能音乐创作系统——从推荐到生成

一、引言&#xff1a;当AI成为音乐创作伙伴 2023年&#xff0c;一款由大语言模型&#xff08;LLM&#xff09;生成的钢琴曲《量子交响曲》在Spotify冲上热搜&#xff0c;引发音乐界震动。传统音乐创作需要数年专业训练&#xff0c;而现代AI技术正在打破这一壁垒。本文提出一种…

VLAN综合实验二

一.实验拓扑&#xff1a; 二.实验需求&#xff1a; 1.内网Ip地址使用172.16.0.0/分配 2.sw1和SW2之间互为备份 3.VRRP/STP/VLAN/Eth-trunk均使用 4.所有Pc均通过DHCP获取IP地址 5.ISP只能配置IP地址 6.所有…

ModuleNotFoundError: No module named ‘ml_logger.logbook‘

问题 (legion) zhouy24RL-DSlab:~/zhouy24Files/legion/LEGION$ python main.py ML_LOGGER_USER is not set. This is required for online usage. Traceback (most recent call last): File “main.py”, line 7, in from mtrl.app.run import run File “/data/zhouy24File…

PyTorch 分布式训练(Distributed Data Parallel, DDP)简介

PyTorch 分布式训练&#xff08;Distributed Data Parallel, DDP&#xff09; 一、DDP 核心概念 torch.nn.parallel.DistributedDataParallel 1. DDP 是什么&#xff1f; Distributed Data Parallel (DDP) 是 PyTorch 提供的分布式训练接口&#xff0c;DistributedDataPara…

【Python】天气数据可视化

1. Python进行数据可视化 在数据分析和科学计算领域&#xff0c;Python凭借其强大的库和简洁的语法&#xff0c;成为了众多开发者和科研人员的首选工具。数据可视化作为数据分析的重要环节&#xff0c;能够帮助我们更直观地理解数据背后的规律和趋势。本文将详细介绍如何使用P…

深度学习4.4笔记

《动手学深度学习》-4.4-笔记 验证数据集&#xff1a;通常是从训练集中划分出来的一部分数据&#xff0c;不要和训练数据混在一起&#xff0c;评估模型好坏的数据集 测试数据集&#xff1a;只用一次的数据集 k-折交叉验证&#xff08;k-Fold Cross-Validation&#xff09;是…