【C++】互斥锁(mutex)

C++ mutex 学习笔记

1. 了解 C++ 中的互斥锁(mutex)

  • 作用:互斥锁是一种用于保护共享资源不被多个线程同时访问的同步机制。它可以确保在任意时刻只有一个线程可以访问共享资源,从而避免数据竞争和不一致性。
  • 优势:提供了一种简单而有效的方法来保护共享资源,确保线程安全性。
  • 发展历程:互斥锁是多线程编程中常用的同步机制,C++ 标准库提供了 std::mutex 类来实现互斥锁。

示例代码

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

std::mutex mtx;

void thread_function(int id) {
    mtx.lock(); // 加锁
    std::cout << "Thread " << id << " is executing..." << std::endl;
    mtx.unlock(); // 解锁
}

int main() {
    std::thread t1(thread_function, 1);
    std::thread t2(thread_function, 2);

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

    return 0;
}

2. 学习 C++ 中的互斥锁的多种应用场景

  • 保护共享资源:互斥锁常用于保护共享资源,确保多个线程不会同时访问或修改共享数据,防止数据竞争。
  • 线程同步:互斥锁可用于实现线程之间的同步,确保多个线程按照指定顺序执行,避免并发执行带来的问题。
  • 避免死锁:正确使用互斥锁可以避免死锁问题,确保线程能够正常执行并释放锁。

示例代码

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

std::mutex mtx;
int shared_data = 0;

void increment_shared_data() {
    mtx.lock();
    ++shared_data;
    mtx.unlock();
}

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

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

    std::cout << "Shared data: " << shared_data << std::endl;

    return 0;
}

3. 掌握 C++ 中的互斥锁的使用技巧

  • 加锁解锁:互斥锁的正确使用包括加锁和解锁两个步骤,确保在访问共享资源时正确加锁,在不需要访问时及时解锁。
  • 避免死锁:避免出现死锁情况,即多个线程相互等待对方释放资源而无法继续执行的情况,可以使用 std::lock_guard 类来自动管理互斥锁的加锁和解锁。
  • 递归锁:互斥锁也支持递归锁,允许同一个线程多次对同一个互斥锁进行加锁,但需要小心避免死锁。

示例代码

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

std::mutex mtx;

void recursive_mutex_function(int count) {
    if (count <= 0) {
        return;
    }
    mtx.lock();
    std::cout << "Mutex locked, count = " << count << std::endl;
    recursive_mutex_function(count - 1);
    mtx.unlock();
}

int main() {
    recursive_mutex_function(5);

    return 0;
}

4. 实战案例分析

  • 多线程数据同步:使用互斥锁确保多个线程对共享数据的安全访问。
#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;
int shared_data = 0;

void increment_shared_data() {
    for (int i = 0; i < 1000; ++i) {
        mtx.lock();
        ++shared_data;
        mtx.unlock();
    }
}

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

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

    std::cout << "Shared data: " << shared_data << std::endl;

    return 0;
}
  • 线程安全容器:使用互斥锁保护标准库提供的线程安全容器,实现多线程环境下的安全操作。
#include <iostream>
#include <thread>
#include <mutex>
#include <vector>

std::mutex mtx;
std::vector<int> data;

void insert_data(int value) {
    mtx.lock();
    data.push_back(value);
    mtx.unlock();
}

int main() {
    std::thread t1([](){
        for (int i = 0; i < 1000; ++i) {
            insert_data(i);
        }
    });

    std::thread t2([](){
        for (int i = 1000; i < 2000; ++i) {
            insert_data(i);
        }
    });

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

    // 输出线程安全容器中的数据
    for (const auto& value : data) {
        std::cout << value << " ";
    }
    std::cout << std::endl;

    return 0;
}
  • 避免资源竞争:使用互斥锁避免资源竞争和死锁问题,确保多线程程序的稳定性和可靠性。
#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx1, mtx2;

void function1() {
    mtx1.lock();
    std::cout << "Function 1 acquired mutex 1" << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟耗时操作
    mtx2.lock();
    std::cout << "Function 1 acquired mutex 2" << std::endl;
    mtx2.unlock();
    mtx1.unlock();
}

void function2() {
    mtx2.lock();
    std::cout << "Function 2 acquired mutex 2" << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟耗时操作
    mtx1.lock();
    std::cout << "Function 2 acquired mutex 1" << std::endl;
    mtx1.unlock();
    mtx2.unlock();
}

int main() {
    std::thread t1(function1);
    std::thread t2(function2);

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

    return 0;
}

通过学习和掌握 C++ 中的互斥锁(mutex),可以更好地保护共享资源,确保多线程程序的正确性和稳定性。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值