C++ std::lock_guard和 std::unique_lock

二者都是 C++ 标准库中用于管理互斥锁(mutex)的 RAII(Resource Acquisition Is Initialization)机制的类。这些类可以确保互斥锁在构造时被获取,在析构时被释放,从而避免死锁和资源泄漏问题。不过,它们在功能和使用方式上有一些重要区别。

std::lock_guard

td::lock_guard 是一个简单的、轻量级的锁管理器,它在构造时获取锁,在析构时释放锁。其主要特点是不能显式地解锁或重新锁定。

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

std::mutex mtx;

void threadFunction(int threadID) {
    try {
        std::lock_guard<std::mutex> lock(mtx);
        // mtx 在此范围内锁定
        std::cout << "Thread " << threadID << " is running..." << std::endl;
        // 模拟一些工作
        std::this_thread::sleep_for(std::chrono::milliseconds(100)); 
        std::cout << "Thread " << threadID << " has finished working." << std::endl;
        // mtx 在此范围末尾解锁
    } catch (const std::exception& e) {
        std::cerr << "Exception caught in thread " << threadID << ": " << e.what() << std::endl;
    }
}

int main() {
    const int numThreads = 5;
    std::vector<std::thread> threads;

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

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

    std::cout << "All threads have completed." << std::endl;

    return 0;
}

 

每个线程在输出信息时获取了互斥锁,确保了标准输出的操作是原子的,避免了竞争条件导致的输出混乱。 

std::unique_lock 

std::unique_lock 是一个灵活但稍复杂的锁管理器。它允许更多的锁操作,如延迟锁定、解锁和重新锁定。

// unique_lock example
#include <iostream>       // std::cout
#include <thread>         // std::thread
#include <mutex>          // std::mutex, std::unique_lock

std::mutex mtx;           // mutex for critical section

void print_block (int n, char c) {
  // critical section (exclusive access to std::cout signaled by lifetime of lck):
  std::unique_lock<std::mutex> lck (mtx);
  for (int i=0; i<n; ++i) { std::cout << c; }
  std::cout << '\n';
}

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

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

  return 0;
}

order of lines may vary, but characters are never mixed. 

void threadFunction() {
    std::unique_lock<std::mutex> lock(mtx);
    // 可以显式解锁
    std::this_thread::sleep_for(std::chrono::seconds(1)); // 模拟工作
    std::cout << "Thread is running..." << std::endl;
    lock.unlock();

    // 可以重新加锁
    lock.lock();
    std::cout << "Thread is finishing..." << std::endl;
}

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

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

    return 0;
}

 

相关推荐

  1. @RequestBody@RequestParam@PathVariable@RequestAttribute

    2024-07-17 20:34:01       50 阅读
  2. ==equals

    2024-07-17 20:34:01       56 阅读
  3. 关于%/

    2024-07-17 20:34:01       40 阅读
  4. nodejsnpmvite

    2024-07-17 20:34:01       48 阅读
  5. computedwatchwatchEffect 相同不同

    2024-07-17 20:34:01       55 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-17 20:34:01       70 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-17 20:34:01       74 阅读
  3. 在Django里面运行非项目文件

    2024-07-17 20:34:01       62 阅读
  4. Python语言-面向对象

    2024-07-17 20:34:01       72 阅读

热门阅读

  1. MySQL 事务

    2024-07-17 20:34:01       23 阅读
  2. 力扣刷题之2956.找到两个数组中的公共元素

    2024-07-17 20:34:01       21 阅读
  3. 前端面试题日常练-day94 【Less】

    2024-07-17 20:34:01       25 阅读
  4. Linux第一章课后作业

    2024-07-17 20:34:01       25 阅读
  5. 免费服务器和付费服务器哪个更好?

    2024-07-17 20:34:01       24 阅读
  6. 云服务器,nginx访问失败,安全组,0.0.0.0/0

    2024-07-17 20:34:01       24 阅读
  7. 网络安全工作者如何解决网络拥堵

    2024-07-17 20:34:01       23 阅读