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

用什么软件写网站荷城网站设计

用什么软件写网站,荷城网站设计,千图网免费素材图库ppt,小企业如何优化网站建设C 中多线程编程的两个核心同步原语:互斥锁 (Mutex) 和 条件变量 (Condition Variable)。它们是实现线程间安全通信和协调的关键。1. 互斥锁 (Mutex)核心概念互斥锁用于保护共享数据,确保同一时间只有一个线程可以访问该数据,从而避免数据竞争…

C++ 中多线程编程的两个核心同步原语:互斥锁 (Mutex)条件变量 (Condition Variable)。它们是实现线程间安全通信和协调的关键。

1. 互斥锁 (Mutex)

核心概念

互斥锁用于保护共享数据,确保同一时间只有一个线程可以访问该数据,从而避免数据竞争 (Data Race)

原理:线程在访问共享数据前先上锁 (lock),如果锁已被其他线程占用,则当前线程阻塞 (block) 等待。访问完成后解锁 (unlock),让其他线程有机会获取锁。

C++ 中的互斥锁 (<mutex> 头文件)

1. std::mutex

最基本的互斥锁。

cpp

#include <iostream>
#include <thread>
#include <mutex>std::mutex g_mutex; // 全局互斥锁
int shared_data = 0;void increment() {for (int i = 0; i < 100000; ++i) {g_mutex.lock();    // 上锁++shared_data;     // 临界区代码g_mutex.unlock();  // 解锁}
}int main() {std::thread t1(increment);std::thread t2(increment);t1.join();t2.join();std::cout << "Final value: " << shared_data << std::endl; // 正确输出 200000return 0;
}
2. std::lock_guard (推荐使用)

RAII 风格的锁管理,在构造时自动上锁,析构时自动解锁,即使发生异常也能保证解锁,避免死锁。

cpp

void safe_increment() {for (int i = 0; i < 100000; ++i) {std::lock_guard<std::mutex> lock(g_mutex); // 构造时上锁,析构时解锁++shared_data;} // lock_guard 在此析构,自动解锁
}
3. std::unique_lock (更灵活)

lock_guard 更灵活,可以手动控制上锁和解锁的时机,是条件变量必需的伙伴。

cpp

void flexible_increment() {for (int i = 0; i < 100000; ++i) {std::unique_lock<std::mutex> lock(g_mutex); // 自动上锁++shared_data;// 可以手动提前解锁,不需要等到作用域结束lock.unlock();// ... 这里可以执行一些不涉及共享数据的操作}
}

2. 条件变量 (Condition Variable)

核心概念

条件变量用于线程间的通信和协调。它允许一个线程等待某个条件成立,而其他线程在条件成立时通知等待的线程。

典型生产者-消费者模式

  • 消费者线程等待"缓冲区不为空"的条件

  • 生产者线程在放入数据后通知消费者

C++ 中的条件变量 (<condition_variable> 头文件)

基本使用模式

cpp

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>std::mutex mtx;
std::condition_variable cv;
std::queue<int> data_queue;
const int MAX_SIZE = 5;// 生产者线程
void producer() {for (int i = 0; i < 10; ++i) {std::unique_lock<std::mutex> lock(mtx);// 等待条件:队列未满// 使用lambda表达式作为等待条件cv.wait(lock, [] { return data_queue.size() < MAX_SIZE; });data_queue.push(i);std::cout << "Produced: " << i << std::endl;lock.unlock(); // 手动解锁(可选,notify之前解锁更好)cv.notify_one(); // 通知一个等待的消费者}
}// 消费者线程
void consumer() {while (true) {std::unique_lock<std::mutex> lock(mtx);// 等待条件:队列不为空cv.wait(lock, [] { return !data_queue.empty(); });int data = data_queue.front();data_queue.pop();std::cout << "Consumed: " << data << std::endl;lock.unlock();cv.notify_one(); // 通知生产者可能有空位了if (data == 9) break; // 收到最后一个数据后退出}
}int main() {std::thread prod(producer);std::thread cons(consumer);prod.join();cons.join();return 0;
}

条件变量的关键方法

  1. wait(lock, predicate):

    • 原子地解锁并阻塞当前线程

    • 被唤醒后重新获取锁

    • 检查 predicate 条件,如果为 false 则继续等待

  2. notify_one():

    • 唤醒一个等待中的线程(如果有)

  3. notify_all():

    • 唤醒所有等待中的线程


3. 为什么条件变量需要互斥锁?

条件变量必须与互斥锁配合使用,原因如下:

  1. 原子性操作:检查条件和进入等待必须是原子操作,否则可能发生:

    • 线程A检查条件 → 条件不满足

    • 线程B修改条件并发出通知

    • 线程A才开始等待 → 通知丢失,线程A永远等待

  2. 保护共享状态:条件变量等待的"条件"通常是共享数据,需要用互斥锁保护。


4. 完整的生产者-消费者示例

cpp

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>class ThreadSafeQueue {
private:std::queue<int> queue_;std::mutex mtx_;std::condition_variable cv_producer_;std::condition_variable cv_consumer_;const int max_size_ = 5;bool stop_ = false;public:void push(int value) {std::unique_lock<std::mutex> lock(mtx_);cv_producer_.wait(lock, [this] { return queue_.size() < max_size_ || stop_; });if (stop_) return;queue_.push(value);std::cout << "Produced: " << value << std::endl;cv_consumer_.notify_one();}int pop() {std::unique_lock<std::mutex> lock(mtx_);cv_consumer_.wait(lock, [this] { return !queue_.empty() || stop_; });if (stop_ && queue_.empty()) return -1;int value = queue_.front();queue_.pop();std::cout << "Consumed: " << value << std::endl;cv_producer_.notify_one();return value;}void stop() {std::lock_guard<std::mutex> lock(mtx_);stop_ = true;cv_producer_.notify_all();cv_consumer_.notify_all();}
};int main() {ThreadSafeQueue queue;std::thread producer([&queue] {for (int i = 0; i < 10; ++i) {queue.push(i);std::this_thread::sleep_for(std::chrono::milliseconds(100));}queue.stop();});std::thread consumer([&queue] {while (true) {int value = queue.pop();if (value == -1) break;std::this_thread::sleep_for(std::chrono::milliseconds(150));}});producer.join();consumer.join();return 0;
}

5. 重要注意事项和最佳实践

  1. 虚假唤醒 (Spurious Wakeup):线程可能在没有收到通知的情况下被唤醒,因此必须使用谓词检查条件。

  2. 优先使用 std::lock_guardstd::unique_lock:避免手动调用 lock()/unlock()

  3. 在通知前解锁:在调用 notify_one()notify_all() 前解锁,可以让被唤醒的线程立即获取锁,提高性能。

  4. 使用 RAII:确保异常安全,所有资源都能正确释放。

  5. 避免嵌套锁:容易导致死锁。

总结对比

特性互斥锁 (Mutex)条件变量 (Condition Variable)
主要目的保护共享数据,避免数据竞争线程间通信和协调
操作lock(), unlock()wait(), notify_one(), notify_all()
配合使用可以单独使用必须与互斥锁配合使用
阻塞原因等待获取锁等待某个条件成立
典型模式临界区保护生产者-消费者

掌握互斥锁和条件变量是编写正确、高效多线程 C++ 程序的基础。

http://www.dtcms.com/a/602161.html

相关文章:

  • 长治哪家公司做网站好怎么做网站教程视频
  • 跟踪导论(三)——滤波的释义位置信息的“观测+修正”
  • 一个电商网站开发周期是多久搜索引擎营销流程是什么?
  • 计算机做网站难吗网站建设费可以走办公费吗
  • 做公众号还是网站建网站哪家划算
  • 从App时代到智能体时代,如何打破“三堵墙”
  • jsp怎么拿到url参数
  • 有机蔬菜:清爽解腻的炖锅搭档
  • 网站的时间对齐应该怎么做wordpress中文评论插件
  • 515ppt网站建设岳麓区专业的建设网站公司
  • mysql第5次作业---hyx
  • LLM的“哥白尼革命”:物理AI与世界模型,AI的下一个战场!
  • VC软件编译C语言 | 详细教程与常见问题解答
  • 高职单招与统招比较及职业发展指南
  • Cursor vs Claude Code:AI编程工具深度对比与选择指南
  • php论坛网站源码下载大型购物网站设计
  • 网站建设标书样本如何修改wordpress登录域名
  • 深圳网站建设联系方式crm客户管理系统论文
  • Python 100例:深入学习与实践指南
  • “系统性”学习高并发路线
  • VL25 输入序列连续的序列检测
  • 如何做条形码网站怎么搞浏览器如何推广自己网站
  • 系统之美—人文行走
  • 用Python和Websockets库构建一个高性能、低延迟的实时消息推送服务
  • 海尔网站建设水平河北廊坊seo网站建设网站优化
  • 小型深圳网站定制开发最专业的网站建设
  • 中山网站优化排名徐州祥云做网站
  • 8、hall速度控制——速度电流双闭环控制(一)
  • 网页版C语言编译器 | 在线体验C语言编程,快速编译与调试
  • 网站如何调用微博网站集群建设是