C++ 线程 一些同步方式

11 篇文章 0 订阅

一些同步方式

在多线程编程中,除了条件变量(condition variable)之外,还有其他几种常见的同步机制,每种机制都有其特定的使用场景和优势。以下是一些常见的同步方式:

1.互斥锁(Mutex)

互斥锁是最基本的同步机制,用于保护共享数据,防止多个线程同时访问导致数据竞争。

示例代码:

#include <iostream>
#include <thread>
#include <mutex>

// 声明一个互斥锁对象
std::mutex mtx;

// 声明一个共享数据变量,初始值为0
int shared_data = 0;

// 线程函数:增加共享数据的值
void increment() {
    // 使用lock_guard锁定互斥锁,确保线程安全
    std::lock_guard<std::mutex> lock(mtx);
    
    // 增加共享数据的值
    shared_data++;
}

int main() {
    // 创建两个线程,每个线程调用increment函数
    std::thread t1(increment);
    std::thread t2(increment);
    
    // 等待两个线程完成
    t1.join();
    t2.join();
    
    // 输出共享数据的最终值
    std::cout << "Shared data: " << shared_data << std::endl;
    
    // 返回0,表示程序正常结束
    return 0;
}


2. 读写锁(Reader-Writer Lock)

读写锁允许多个读线程同时访问共享数据,但写线程独占访问。适用于读多写少的场景。

示例代码:

#include <iostream>
#include <thread>
#include <shared_mutex>

// 声明一个读写锁对象
std::shared_mutex rw_mtx;

// 声明一个共享数据变量,初始值为0
int shared_data = 0;

// 读线程函数:读取共享数据的值
void read() {
    // 使用shared_lock锁定读写锁,允许多个读线程同时访问
    std::shared_lock<std::shared_mutex> lock(rw_mtx);
    
    // 输出读取到的共享数据的值
    std::cout << "Read data: " << shared_data << std::endl;
}

// 写线程函数:增加共享数据的值
void write() {
    // 使用unique_lock锁定读写锁,独占访问,阻止其他读写线程
    std::unique_lock<std::shared_mutex> lock(rw_mtx);
    
    // 增加共享数据的值
    shared_data++;
    
    // 输出写入后的共享数据的值
    std::cout << "Write data: " << shared_data << std::endl;
}

int main() {
    // 创建一个读线程和一个写线程
    std::thread t1(read);
    std::thread t2(write);
    
    // 等待两个线程完成
    t1.join();
    t2.join();
    
    // 返回0,表示程序正常结束
    return 0;
}

3. 信号量(Semaphore)

信号量用于控制对共享资源的访问,可以用于线程间的同步和互斥。

示例代码:

#include <iostream>
#include <thread>
#include <semaphore>

// 声明一个计数信号量对象,初始值为1
std::counting_semaphore<1> sem(1);

// 声明一个共享数据变量,初始值为0
int shared_data = 0;

// 线程函数:增加共享数据的值
void increment() {
    // 获取信号量,阻塞直到信号量可用
    sem.acquire();
    
    // 增加共享数据的值
    shared_data++;
    
    // 释放信号量,允许其他线程获取
    sem.release();
}

int main() {
    // 创建两个线程,每个线程调用increment函数
    std::thread t1(increment);
    std::thread t2(increment);
    
    // 等待两个线程完成
    t1.join();
    t2.join();
    
    // 输出共享数据的最终值
    std::cout << "Shared data: " << shared_data << std::endl;
    
    // 返回0,表示程序正常结束
    return 0;
}

4. 原子操作(Atomic)

原子操作提供了一种无锁的同步机制,适用于对单个变量的简单操作。

示例代码:

#include <iostream>
#include <thread>
#include <atomic>

// 声明一个原子整数变量,初始值为0
std::atomic<int> shared_data(0);

// 线程函数:增加共享数据的值
void increment() {
    // 使用原子操作增加共享数据的值
    shared_data++;
}

int main() {
    // 创建两个线程,每个线程调用increment函数
    std::thread t1(increment);
    std::thread t2(increment);
    
    // 等待两个线程完成
    t1.join();
    t2.join();
    
    // 输出共享数据的最终值
    std::cout << "Shared data: " << shared_data << std::endl;
    
    // 返回0,表示程序正常结束
    return 0;
}

5. 屏障(Barrier)

#include <iostream>
#include <thread>
#include <barrier>

// 声明一个屏障对象,初始计数为3
std::barrier bar(3);

// 工作线程函数:模拟工作并使用屏障进行同步
void worker() {
    // 输出工作线程开始的信息
    std::cout << "Worker started" << std::endl;
    
    // 到达屏障并等待,直到所有线程都到达屏障
    bar.arrive_and_wait();
    
    // 输出工作线程结束的信息
    std::cout << "Worker finished" << std::endl;
}

int main() {
    // 创建三个线程,每个线程调用worker函数
    std::thread t1(worker);
    std::thread t2(worker);
    std::thread t3(worker);
    
    // 等待三个线程完成
    t1.join();
    t2.join();
    t3.join();
    
    // 返回0,表示程序正常结束
    return 0;
}

6. 条件变量(Condition Variable)

条件变量用于在一个线程等待某个条件成立时挂起该线程,并在条件成立时通知该线程继续执行。

示例代码:

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

// 声明一个互斥锁对象
std::mutex mtx;

// 声明一个条件变量对象
std::condition_variable cv;

// 声明一个布尔变量,用于表示条件是否成立
bool ready = false;

// 工作线程函数:等待条件成立并开始工作
void worker() {
    // 使用unique_lock锁定互斥锁
    std::unique_lock<std::mutex> lock(mtx);
    
    // 等待条件变量,直到ready为true
    cv.wait(lock, []{ return ready; });
    
    // 输出工作线程开始的信息
    std::cout << "Worker started" << std::endl;
}

// 触发线程函数:设置条件并通知等待的线程
void trigger() {
    // 使用lock_guard锁定互斥锁
    std::lock_guard<std::mutex> lock(mtx);
    
    // 设置ready为true,表示条件成立
    ready = true;
    
    // 通知一个等待的线程
    cv.notify_one();
}

int main() {
    // 创建一个工作线程和一个触发线程
    std::thread t1(worker);
    std::thread t2(trigger);
    
    // 等待两个线程完成
    t1.join();
    t2.join();
    
    // 返回0,表示程序正常结束
    return 0;
}

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MarkTop1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值