117.info
人生若只如初见

Linux C++多线程同步怎么做

在Linux环境下使用C++进行多线程编程时,线程同步是一个重要的问题。线程同步的目的是确保多个线程能够安全地访问共享资源,避免数据竞争和不一致性。以下是一些常用的线程同步机制:

1. 互斥锁(Mutex)

互斥锁是最基本的同步机制之一,用于保护共享资源,确保同一时间只有一个线程可以访问该资源。

#include 
#include 
#include 

std::mutex mtx; // 全局互斥锁

void print_block(int n, char c) {
    mtx.lock(); // 加锁
    for (int i = 0; i < n; ++i) {
        std::cout << c;
    }
    std::cout << '\n';
    mtx.unlock(); // 解锁
}

int main() {
    std::thread th1(print_block, 50, '*');
    std::thread th2(print_block, 50, '$');

    th1.join();
    th2.join();

    return 0;
}

2. 递归互斥锁(Recursive Mutex)

递归互斥锁允许同一个线程多次锁定同一个互斥锁,而不会导致死锁。

#include 
#include 
#include 

std::recursive_mutex mtx;

void foo() {
    mtx.lock();
    std::cout << "foo\n";
    mtx.lock(); // 再次锁定
    std::cout << "foo again\n";
    mtx.unlock();
    mtx.unlock();
}

int main() {
    std::thread th(foo);
    th.join();
    return 0;
}

3. 条件变量(Condition Variable)

条件变量用于线程间的等待和通知机制,常与互斥锁一起使用。

#include 
#include 
#include 
#include 

std::mutex mtx;
std::condition_variable cv;
bool ready = false;

void print_id(int id) {
    std::unique_lock lck(mtx);
    cv.wait(lck, []{return ready;}); // 等待条件变量
    std::cout << "Thread " << id << '\n';
}

void go() {
    std::unique_lock lck(mtx);
    ready = true;
    cv.notify_all(); // 通知所有等待的线程
}

int main() {
    std::thread threads[10];
    for (int i = 0; i < 10; ++i) {
        threads[i] = std::thread(print_id, i);
    }
    std::this_thread::sleep_for(std::chrono::seconds(1));
    go();
    for (auto &th : threads) {
        th.join();
    }
    return 0;
}

4. 原子操作(Atomic Operations)

原子操作是不可分割的操作,可以确保在多线程环境下对变量的操作是线程安全的。

#include 
#include 
#include 

std::atomic counter(0);

void increment() {
    for (int i = 0; i < 100000; ++i) {
        counter.fetch_add(1, std::memory_order_relaxed); // 原子加法
    }
}

int main() {
    std::thread t1(increment);
    std::thread t2(increment);

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

    std::cout << "Counter: " << counter.load() << '\n';
    return 0;
}

5. 屏障(Barrier)

屏障用于确保多个线程在某个点上同步,所有线程都到达屏障点后才能继续执行。

#include 
#include 
#include 
#include 

std::barrier sync_point(3); // 创建一个屏障,等待3个线程

void do_work(int id) {
    std::cout << "Thread " << id << " is working\n";
    sync_point.arrive_and_wait(); // 等待其他线程
    std::cout << "Thread " << id << " has passed the barrier\n";
}

int main() {
    std::vector threads;
    for (int i = 0; i < 3; ++i) {
        threads.emplace_back(do_work, i);
    }
    for (auto &th : threads) {
        th.join();
    }
    return 0;
}

这些是C++多线程编程中常用的同步机制。根据具体的需求选择合适的同步机制,可以有效地避免多线程编程中的常见问题。

未经允许不得转载 » 本文链接:https://www.117.info/ask/fe738AzsNAAJfB1Y.html

推荐文章

  • Hadoop集群搭建有哪些关键步骤

    搭建Hadoop集群的关键步骤主要包括以下几个方面:
    前期准备 硬件准备 确定集群规模(节点数量)。
    选择合适的服务器配置(CPU、内存、存储)。
    确...

  • Linux GitLab权限怎么设置

    在Linux上设置GitLab权限,可以按照以下步骤进行:
    1. 安装和配置GitLab
    首先,确保你已经按照官方文档在Linux上安装了GitLab。
    2. 创建管理员账...

  • Linux系统如何安装MinIO服务

    在Linux系统上安装MinIO服务的步骤如下:
    1. 下载MinIO二进制文件
    首先,你需要从MinIO的官方网站下载适用于你系统的MinIO二进制文件。你可以使用以下...

  • Linux Oracle安全设置指南

    在Linux系统上配置Oracle数据库的安全性是一个重要的步骤,可以有效地保护数据免受未授权访问和其他安全威胁。以下是一个详细的Linux Oracle安全设置指南:

  • Node.js在Linux中如何优化性能

    在Linux环境下对Node.js进行性能优化是一个复杂但至关重要的过程,它涉及到多个层面的优化策略。以下是一些关键的优化技巧和工具,可以帮助提升Node.js应用程序的...

  • Compton与Xorg在Debian上的兼容性如何

    Compton与Xorg在Debian上的兼容性通常是良好的,因为Compton是一个轻量级的窗口合成器,它依赖于Xorg显示服务器来渲染图形。以下是一些关键点: 依赖关系:Compt...

  • CentOS Redis如何高效配置

    在CentOS上高效配置Redis涉及多个步骤,包括安装、基本配置、性能优化和高并发处理。以下是详细的步骤和建议:
    安装Redis 安装依赖: sudo yum install -y ...

  • Debian VNC如何实现多用户同时连接

    要在Debian系统上实现多用户同时连接VNC,可以按照以下步骤进行配置: 安装VNC服务器和桌面环境: 更新软件包列表:sudo apt update 安装Xfce桌面环境:sudo apt...