当前位置: 首页 > wzjs >正文

企业网站图片渐变效果怎么做企业应该如何进行网站推广

企业网站图片渐变效果怎么做,企业应该如何进行网站推广,自己做的动画买给网站,广告营销是什么意思C学习:六个月从基础到就业——多线程编程:互斥量与锁 本文是我C学习之旅系列的第五十五篇技术文章,也是第四阶段"并发与高级主题"的第二篇,介绍C11及以后标准中的互斥量(mutex)、锁(l…

C++学习:六个月从基础到就业——多线程编程:互斥量与锁

本文是我C++学习之旅系列的第五十五篇技术文章,也是第四阶段"并发与高级主题"的第二篇,介绍C++11及以后标准中的互斥量(mutex)、锁(lock)等线程同步基础。查看完整系列目录了解更多内容。

引言

多线程程序中,多个线程对共享资源的访问会导致数据竞争和不确定行为。为保证数据一致性和线程安全,C++标准库提供了多种同步原语,其中最基础的就是互斥量(std::mutex)和各种锁(std::lock_guardstd::unique_lock等)。本篇将系统讲解C++中的互斥量与锁的用法、原理及常见陷阱。

目录

  • 多线程编程:互斥量与锁
    • 引言
    • 目录
    • 互斥量基础
      • std::mutex的基本用法
      • std::lock_guard与RAII
      • std::unique_lock与灵活锁管理
      • 递归互斥量std::recursive_mutex
      • 定时锁定std::timed_mutex
    • 多锁与死锁预防
      • std::lock和std::scoped_lock
      • 避免死锁的常用策略
    • 读写锁(共享互斥量)
      • std::shared_mutex与std::shared_lock
    • 实际应用案例
      • 线程安全的计数器
      • 线程安全的队列
    • 常见问题与陷阱
      • 死锁与活锁
      • 锁粒度与性能
      • 异常安全与锁
    • 总结

互斥量基础

std::mutex的基本用法

std::mutex是C++11标准库提供的最基础的互斥量类型。它用于保护临界区,确保同一时刻只有一个线程可以访问共享资源。

#include <iostream>
#include <thread>
#include <mutex>int counter = 0;
std::mutex counterMutex;void increment(int times) {for (int i = 0; i < times; ++i) {counterMutex.lock();++counter;counterMutex.unlock();}
}int main() {std::thread t1(increment, 100000);std::thread t2(increment, 100000);t1.join();t2.join();std::cout << "Final counter: " << counter << std::endl;return 0;
}

手动调用lock()unlock()容易出错,推荐使用RAII风格的锁管理。

std::lock_guard与RAII

std::lock_guard是最简单的RAII锁管理器,构造时加锁,析构时自动解锁,适合简单场景。

#include <mutex>std::mutex mtx;void safeFunction() {std::lock_guard<std::mutex> lock(mtx); // 构造时加锁// 临界区
} // 离开作用域自动解锁

优点:

  • 避免忘记解锁
  • 异常安全

std::unique_lock与灵活锁管理

std::unique_locklock_guard更灵活,支持延迟加锁、提前解锁、锁的转移等。

#include <mutex>std::mutex mtx;void flexibleFunction() {std::unique_lock<std::mutex> lock(mtx, std::defer_lock); // 不立即加锁// ...做一些准备...lock.lock(); // 手动加锁// ...临界区...lock.unlock(); // 手动解锁// ...非临界区...lock.lock(); // 重新加锁// ...再次进入临界区...
} // 离开作用域自动解锁(如果还持有锁)

unique_lock还可以与std::lock配合实现多互斥量的安全加锁。

递归互斥量std::recursive_mutex

递归互斥量允许同一线程多次获得同一个锁,适用于递归调用场景。

#include <mutex>std::recursive_mutex recMtx;void recursiveFunc(int n) {if (n <= 0) return;std::lock_guard<std::recursive_mutex> lock(recMtx);// ...临界区...recursiveFunc(n - 1); // 递归调用
}

注意:递归互斥量开销更大,非必要时应避免使用。

定时锁定std::timed_mutex

std::timed_mutexstd::recursive_timed_mutex支持超时锁定:

#include <mutex>
#include <chrono>
#include <iostream>std::timed_mutex tmtx;void tryLockWithTimeout() {if (tmtx.try_lock_for(std::chrono::milliseconds(100))) {std::cout << "Lock acquired" << std::endl;tmtx.unlock();} else {std::cout << "Timeout, lock not acquired" << std::endl;}
}

多锁与死锁预防

std::lock和std::scoped_lock

std::lock可以一次性安全地锁定多个互斥量,避免死锁。C++17引入了std::scoped_lock,更简洁:

#include <mutex>std::mutex m1, m2;void safeMultiLock() {std::scoped_lock lock(m1, m2); // 同时加锁,顺序无关// ...临界区...
}

避免死锁的常用策略

  1. 始终以相同顺序加锁
  2. 使用std::lock/std::scoped_lock
  3. 尽量缩小锁的作用域
  4. 避免在持锁时调用用户回调

读写锁(共享互斥量)

std::shared_mutex与std::shared_lock

C++17引入了std::shared_mutex,允许多个线程同时读,但写时独占。

#include <shared_mutex>
#include <thread>
#include <iostream>std::shared_mutex rwMutex;
int sharedData = 0;void reader() {std::shared_lock lock(rwMutex);std::cout << "Read: " << sharedData << std::endl;
}void writer(int value) {std::unique_lock lock(rwMutex);sharedData = value;std::cout << "Write: " << sharedData << std::endl;
}

适用于读多写少的场景。

实际应用案例

线程安全的计数器

#include <mutex>class SafeCounter {int value = 0;std::mutex mtx;
public:void increment() {std::lock_guard<std::mutex> lock(mtx);++value;}int get() {std::lock_guard<std::mutex> lock(mtx);return value;}
};

线程安全的队列

#include <queue>
#include <mutex>
#include <condition_variable>
#include <optional>template<typename T>
class ThreadSafeQueue {std::queue<T> q;std::mutex mtx;std::condition_variable cv;
public:void push(T value) {{std::lock_guard<std::mutex> lock(mtx);q.push(std::move(value));}cv.notify_one();}std::optional<T> pop() {std::unique_lock<std::mutex> lock(mtx);if (q.empty()) return std::nullopt;T value = std::move(q.front());q.pop();return value;}// 支持阻塞等待T wait_and_pop() {std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, [this]{ return !q.empty(); });T value = std::move(q.front());q.pop();return value;}
};

常见问题与陷阱

死锁与活锁

  • 死锁:多个线程互相等待对方释放锁,导致程序卡死。
  • 活锁:线程不断尝试获取锁但始终失败,导致无进展。

避免方法:使用std::lock/std::scoped_lock,保持加锁顺序一致,缩小锁粒度。

锁粒度与性能

  • 粗粒度锁:简单但可能降低并发性能
  • 细粒度锁:提高并发,但设计复杂,易出错

建议:根据实际需求权衡,优先保证正确性。

异常安全与锁

RAII锁(如lock_guardunique_lock)能确保异常发生时自动释放锁,避免死锁。

总结

互斥量和锁是C++多线程同步的基础。合理使用std::mutexstd::lock_guardstd::unique_lockstd::scoped_lock等工具,可以有效避免数据竞争和死锁问题。C++17/20引入的shared_mutexscoped_lock等进一步提升了并发性能和代码简洁性。

在下一篇文章中,我们将继续学习条件变量(std::condition_variable),它是实现线程间通信和同步的关键工具。


这是我C++学习之旅系列的第五十五篇技术文章。查看完整系列目录了解更多内容。

http://www.dtcms.com/wzjs/358006.html

相关文章:

  • 直接用apk 做登陆网站搜索引擎查重
  • 怎么自己优化网站小程序如何推广运营
  • 北京高端网站公司哪家好长沙全网推广
  • 个人网站的制作论文google play下载
  • 怎么设置网站关键字经典软文案例和扶贫农产品软文
  • 做网站需要看那几点网络营销专业是干嘛的
  • 自己做网站怎么别人怎么浏览百度上首页
  • 南京做网站的额河南seo外包
  • 呼市网站建设郑州网络推广排名
  • wordpress 文章404杭州网站优化服务
  • 天津网站seo策划买卖友情链接
  • 辽宁省城乡和住房建设厅老网站网络营销策划方案模板范文
  • 画廊网站建设河北网站seo
  • 徐州沛县网站建设营销软文范文
  • 怎样申请网站空间网站seo完整seo优化方案
  • 杨浦企业网站建设seo自学教程
  • 云南公司网站制作360关键词排名百度
  • 贵州住房和城乡建设厅旧网站老王搜索引擎入口
  • 广州一起做网站电子商务营销
  • 仪征做网站公司哪家好bt搜索引擎下载
  • 广州做蛋糕的网站四川网络推广seo
  • 建三江廉政建设网站专业网站建设
  • 网页界面设计的起源西安seo优化顾问
  • 石景山做网站公司seo管理平台
  • 欧亚达网站是哪家公司做的网络营销推广目标
  • 站内优化网站怎么做搜外网
  • 优秀的网页网站设计百度反馈中心
  • 照片编辑器手机版优化大师免费安装下载
  • 自己做国际网站深圳推广网络
  • 平面设计类网站什么颜色好在线crm