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

C++并发编程与线程安全

C++并发编程与线程安全

并发编程是现代C++中的重要主题。通过多线程技术,程序可以充分利用多核处理器的性能,提高程序的响应速度和吞吐量。

std::thread是C++11引入的标准线程库,提供了跨平台的线程创建和管理功能。

#include
#include
#include
#include

void worker_function(int id) {
std::cout << "Thread " << id << " starting\n";
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::cout << "Thread " << id << " finished\n";
}

void basic_thread_example() {
std::vector threads;

for (int i = 0; i < 5; ++i) {
threads.emplace_back(worker_function, i);
}

for (auto& t : threads) {
t.join();
}
}

互斥锁是保护共享数据的基本机制,确保同一时刻只有一个线程访问临界区。

#include

class Counter {
int value_;
mutable std::mutex mutex_;

public:
Counter() : value_(0) {}

void increment() {
std::lock_guard lock(mutex_);
++value_;
}

void add(int delta) {
std::lock_guard lock(mutex_);
value_ += delta;
}

int get() const {
std::lock_guard lock(mutex_);
return value_;
}
};

void mutex_example() {
Counter counter;
std::vector threads;

for (int i = 0; i < 10; ++i) {
threads.emplace_back([&counter]() {
for (int j = 0; j < 1000; ++j) {
counter.increment();
}
});
}

for (auto& t : threads) {
t.join();
}

std::cout << "Final count: " << counter.get() << "\n";
}

条件变量用于线程间的同步,允许线程等待特定条件成立。

#include
#include

template
class ThreadSafeQueue {
std::queue queue_;
mutable std::mutex mutex_;
std::condition_variable cond_;

public:
void push(T value) {
std::lock_guard lock(mutex_);
queue_.push(std::move(value));
cond_.notify_one();
}

bool try_pop(T& value) {
std::lock_guard lock(mutex_);
if (queue_.empty()) {
return false;
}
value = std::move(queue_.front());
queue_.pop();
return true;
}

void wait_and_pop(T& value) {
std::unique_lock lock(mutex_);
cond_.wait(lock, [this] { return !queue_.empty(); });
value = std::move(queue_.front());
queue_.pop();
}

bool empty() const {
std::lock_guard lock(mutex_);
return queue_.empty();
}
};

void producer_consumer_example() {
ThreadSafeQueue queue;

std::thread producer([&queue]() {
for (int i = 0; i < 10; ++i) {
queue.push(i);
std::cout << "Produced: " << i << "\n";
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
});

std::thread consumer([&queue]() {
for (int i = 0; i < 10; ++i) {
int value;
queue.wait_and_pop(value);
std::cout << "Consumed: " << value << "\n";
}
});

producer.join();
consumer.join();
}

原子操作提供了无锁的线程安全机制,适用于简单的数据类型。

#include

class AtomicCounter {
std::atomic value_;

public:
AtomicCounter() : value_(0) {}

void increment() {
value_.fetch_add(1, std::memory_order_relaxed);
}

int get() const {
return value_.load(std::memory_order_relaxed);
}

bool compare_and_swap(int expected, int desired) {
return value_.compare_exchange_strong(expected, desired);
}
};

void atomic_example() {
AtomicCounter counter;
std::vector threads;

for (int i = 0; i < 10; ++i) {
threads.emplace_back([&counter]() {
for (int j = 0; j < 1000; ++j) {
counter.increment();
}
});
}

for (auto& t : threads) {
t.join();
}

std::cout << "Atomic count: " << counter.get() << "\n";
}

读写锁允许多个读者同时访问,但写者独占访问。

#include

class SharedData {
mutable std::shared_mutex mutex_;
std::vector data_;

public:
void write(int value) {
std::unique_lock lock(mutex_);
data_.push_back(value);
}

int read(size_t index) const {
std::shared_lock lock(mutex_);
if (index < data_.size()) {
return data_[index];
}
return -1;
}

size_t size() const {
std::shared_lock lock(mutex_);
return data_.size();
}
};

void reader_writer_example() {
SharedData data;

std::thread writer([&data]() {
for (int i = 0; i < 100; ++i) {
data.write(i);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
});

std::vector readers;
for (int i = 0; i < 5; ++i) {
readers.emplace_back([&data, i]() {
for (int j = 0; j < 50; ++j) {
size_t size = data.size();
if (size > 0) {
int value = data.read(size - 1);
std::cout << "Reader " << i << " read: " << value << "\n";
}
std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
});
}

writer.join();
for (auto& r : readers) {
r.join();
}
}

线程池可以复用线程,避免频繁创建和销毁线程的开销。

#include

class ThreadPool {
std::vector workers_;
ThreadSafeQueue> tasks_;
std::atomic stop_;

public:
explicit ThreadPool(size_t num_threads) : stop_(false) {
for (size_t i = 0; i < num_threads; ++i) {
workers_.emplace_back([this]() {
while (!stop_.load()) {
std::function task;
if (tasks_.try_pop(task)) {
task();
} else {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
});
}
}

~ThreadPool() {
stop_.store(true);
for (auto& worker : workers_) {
if (worker.joinable()) {
worker.join();
}
}
}

template
void submit(F&& task) {
tasks_.push(std::forward(task));
}
};

void thread_pool_example() {
ThreadPool pool(4);

for (int i = 0; i < 20; ++i) {
pool.submit([i]() {
std::cout << "Task " << i << " executing\n";
std::this_thread::sleep_for(std::chrono::milliseconds(100));
});
}

std::this_thread::sleep_for(std::chrono::seconds(3));
}

future和promise提供了异步操作的结果传递机制。

#include

int compute_value(int x) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
return x * x;
}

void future_promise_example() {
std::future result = std::async(std::launch::async, compute_value, 10);

std::cout << "Computing...\n";
int value = result.get();
std::cout << "Result: " << value << "\n";

std::promise promise;
std::future future = promise.get_future();

std::thread([&promise]() {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
promise.set_value(42);
}).detach();

std::cout << "Waiting for promise...\n";
std::cout << "Promise value: " << future.get() << "\n";
}

死锁是并发编程中常见的问题,需要通过正确的锁顺序或超时机制来避免。

class BankAccount {
int balance_;
mutable std::mutex mutex_;

public:
explicit BankAccount(int balance) : balance_(balance) {}

void transfer(BankAccount& to, int amount) {
std::lock(mutex_, to.mutex_);
std::lock_guard lock1(mutex_, std::adopt_lock);
std::lock_guard lock2(to.mutex_, std::adopt_lock);

if (balance_ >= amount) {
balance_ -= amount;
to.balance_ += amount;
}
}

int balance() const {
std::lock_guard lock(mutex_);
return balance_;
}
};

void deadlock_avoidance_example() {
BankAccount acc1(1000);
BankAccount acc2(2000);

std::thread t1([&]() {
for (int i = 0; i < 100; ++i) {
acc1.transfer(acc2, 10);
}
});

std::thread t2([&]() {
for (int i = 0; i < 100; ++i) {
acc2.transfer(acc1, 10);
}
});

t1.join();
t2.join();

std::cout << "Account 1: " << acc1.balance() << "\n";
std::cout << "Account 2: " << acc2.balance() << "\n";
}

并发编程需要仔细设计和测试,以确保程序的正确性和性能。理解各种同步机制的特点和适用场景,是编写高质量并发代码的关键。

http://www.cnnetsun.cn/news/2507487.html

相关文章:

  • KMS_VL_ALL_AIO:三步永久激活Windows和Office的智能解决方案
  • Minecraft服务器动态内容注入:PlaceholderAPI架构设计与性能优化实践
  • 清晰透明的用量看板与账单,让Taotoken上的每一分Token花费都心中有数
  • 如何快速配置Bilibili-Evolved:打造完美快捷键体验的终极指南
  • Unity AI Chat Toolkit:5分钟打造智能对话应用的终极指南
  • SQLite Viewer:在浏览器中直接查看数据库的零安装神器
  • 观测C语言程序调用大模型API的延迟与稳定性表现
  • Wechaty Puppet WeChat实战指南:构建稳定可靠的微信自动化助手
  • 毫米级精准不复杂!YOLO26 姿态模型在前臂解剖点检测的对比研究
  • 终极指南:使用elan轻松管理Lean定理证明器版本 [特殊字符]
  • eLabFTW:重新定义实验室数字化的开源利器,让科研管理变得简单高效
  • 为内部知识库问答系统接入Taotoken提供稳定可靠的AI理解能力
  • LangGraph 节点依赖管理:拓扑排序+循环依赖检测的实现
  • 智能网盘直链解析工具:免会员下载加速的全新解决方案
  • Go操作Kubernetes API、Service Mesh(Linkerd)集成、Serverless函数编写
  • 终极指南:如何在Windows上快速搭建企业级Hadoop开发环境
  • 如何用Rufus制作专业级USB启动盘:从新手到专家的完整指南
  • 终极指南:如何在5分钟内为MicroPython项目添加ST7789显示屏驱动
  • 别再一个字一个字硬憋了!书匠策AI教你用“外挂级“操作把毕业论文从0拖到100
  • HoRain云--Claude Code 交互模式
  • 原神抽卡记录分析工具:免费开源方案助你掌握抽卡数据
  • MicroPython嵌入式开发:如何用ST7789py_mpy驱动库打造高性能显示方案
  • Html2Pdf高级用法解析:10个实用技巧提升PDF生成效率
  • Promptable社区贡献指南:如何参与这个革命性AI工具的开发
  • 如何在macOS上为Intel Wi-Fi网卡选择最佳驱动方案:itlwm与AirportItlwm深度解析
  • 深度解析PySODMetrics:显著性目标检测的标准化评估框架设计
  • Windows系统下的Touch Bar完整驱动解决方案:解锁MacBook Pro触摸栏全部潜能
  • 书匠策AI:你的毕业论文“外挂“已上线,这功能也太懂大学生了吧!
  • 数字化精细管控,赋能暖心康养服务
  • 如何快速获取精准逐字歌词?LDDC歌词工具的终极完整解决方案