【C++多线程编程】(二)之详解锁(lock)和解锁(unlock)

在C++多线程编程中,锁(lock)和解锁(unlock)通常用于管理共享资源的访问,以防止多个线程同时对资源进行修改,从而避免竞态条件(Race Condition)和数据不一致性问题。C++标准库提供了一些工具来实现锁,其中最常用的是互斥锁(std::mutex)和锁卫士(std::lock_guard)。

以下是一个简单的示例,演示了如何在C++中使用互斥锁和锁卫士:

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

std::mutex myMutex;  // 定义一个互斥锁

void sharedResourceFunction(int id) {
    // 在代码块中使用锁卫士,lock_guard 在构造时锁住互斥锁,在析构时释放锁
    std::lock_guard<std::mutex> lock(myMutex);

    // 在这个代码块中,对共享资源进行读写操作是安全的
    std::cout << "Thread " << id << " is accessing the shared resource." << std::endl;

    // 在这个代码块结束后,锁会自动释放,即使发生了异常
}

int main() {
    const int numThreads = 3;
    std::thread threads[numThreads];

    for (int i = 0; i < numThreads; ++i) {
        threads[i] = std::thread(sharedResourceFunction, i + 1);
    }

    for (int i = 0; i < numThreads; ++i) {
        threads[i].join();
    }

    return 0;
}

1、std::mutex myMutex;:这一行定义了一个互斥锁对象 myMutex。互斥锁用于保护共享资源,确保在任何时候只有一个线程可以访问它。

2、std::lock_guardstd::mutex lock(myMutex);:这一行创建了一个 std::lock_guard 对象,它在构造时锁住 myMutex,在析构时释放锁。这确保了在进入 sharedResourceFunction 函数时锁被锁住,在函数结束时锁被自动释放。这种自动释放锁的方式避免了忘记手动释放锁的问题。

3、std::cout << “Thread " << id << " is accessing the shared resource.” << std::endl;:在锁保护的代码块中对共享资源进行操作。在这个例子中,只是简单地打印一条信息。

4、std::thread threads[numThreads];:创建了一个包含 numThreads 个线程的数组。

5、threads[i] = std::thread(sharedResourceFunction, i + 1);:创建了多个线程,每个线程都调用 sharedResourceFunction 函数,并传递不同的线程ID(1、2、3)。

6、threads[i].join();:等待所有线程执行完毕。调用 join 保证主线程等待所有子线程执行完毕后再继续执行,防止主线程提前退出导致子线程被强制终止。

总体而言,这个例子演示了如何使用互斥锁和锁卫士确保多个线程对共享资源的安全访问。在实际应用中,需要根据具体情况选择适当的同步机制和锁类型。

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C++中,`std::unique_lock`是一个灵活的互斥量封装类,用于处理多线程同步问题。它提供了更多的灵活性和功能,比起`std::lock_guard`更常用。 以下是一个使用`std::unique_lock`解决多线程问题的示例: ```cpp #include <iostream> #include <thread> #include <mutex> std::mutex mtx; // 定义一个互斥量 void printMessage(const std::string& message) { std::unique_lock<std::mutex> lock(mtx); // 创建一个unique_lock住互斥量 for (int i = 0; i < 5; ++i) { std::cout << message << std::endl; } lock.unlock(); // 解锁互斥量 } int main() { std::thread t1(printMessage, "Thread 1"); std::thread t2(printMessage, "Thread 2"); t1.join(); t2.join(); return 0; } ``` 在上述示例中,我们定义了一个全局的`std::mutex`对象`mtx`作为互斥量。然后,我们创建了两个线程`t1`和`t2`,并且每个线程调用`printMessage`函数来输出一定次数的消息。 在`printMessage`函数中,我们首先创建了一个`std::unique_lock<std::mutex>`对象`lock`,并且通过构造函数将互斥量`mtx`作为参数传递进去。这样,`lock`对象会自动住互斥量,确保只有一个线程能够进入临界区。 在临界区内,我们输出了一定次数的消息。由于互斥量的保护,每个线程会按照顺序输出自己的消息,避免了竞争条件。最后,我们调用`lock.unlock()`手动解锁互斥量。 在`main`函数中,我们创建了两个线程并启动它们,然后通过`join()`函数等待线程结束。 通过使用`std::unique_lock`,我们可以更灵活地控制互斥量的定和解锁时机,并且提供了更多的同步操作,比如条件变量等。这样可以有效地处理多线程之间的同步和竞争条件问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

SensizliKLoU

感谢您的慷慨支持和鼓励!

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

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

打赏作者

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

抵扣说明:

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

余额充值