C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > C++ 同步机制 std::mutex

C++ 同步机制 std::mutex的实现示例

作者:恋恋西风

本文主要介绍了C++ 同步机制 std::mutex,读懂std::mutex、recursive_mutex与timed_mutex的核心区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

std::mutex:最基本的互斥量。

std::recursive_mutex:可重入互斥量,允许同一个线程多次加锁。 •std::timed_mutex / std::recursive_timed_mutex:带超时功能的互斥量 (try_lock_for, try_lock_until)。

这三个互斥量(mutex)构成了 C++ 标准库中最基本的同步工具家族。它们的关系可以概括为:std::mutex 是“基础款”,std::recursive_mutex 是“允许重复锁”的变种,而 std::timed_mutex 和 std::recursive_timed_mutex 则是给前两者加上了“超时等待”功能的升级版。

为了让你更直观地理解,可以把它们想象成不同规则的门锁:

核心区别与联系一览

特性std::mutexstd::recursive_mutexstd::timed_mutexstd::recursive_timed_mutex
可重复加锁 (同一线程)❌ 不允许,再次加锁会导致死锁。✅ 允许,需要相同次数的解锁。❌ 不允许✅ 允许
超时等待功能❌ 没有,lock() 会一直阻塞。❌ 没有✅ 有 try_lock_for 和 try_lock_until✅ 有 try_lock_for 和 try_lock_until
性能开销最低较高(需要维护锁计数)较高(需要计时机制)最高(功能最复杂)
适用场景绝大多数简单的、非递归的互斥场景。函数递归调用,或函数A调用函数B且两者需锁同一资源。需要避免死等,实现超时重试或取消操作。同时需要递归和超时功能的复杂场景。

详细解析与代码示例

1.std::mutex:最基础的互斥量

这是最常用、性能最好的互斥量。但它有一个严格规则:同一个线程不能对它加锁两次。

#include <mutex>
std::mutex mtx;
void func() {
    std::lock_guard<std::mutex> lock(mtx); 
    // 任何在此再次尝试对 mtx 加锁的操作都会导致未定义行为,通常是死锁
}

✅ 最佳实践:在绝大多数情况下,优先使用 std::mutex。它足够快,且能迫使你设计出更清晰的锁结构。

2.std::recursive_mutex:允许“重入”的互斥量

它允许同一个线程多次获得同一把锁。内部会维护一个“锁计数器”,每加锁一次+1,每解锁一次-1,直到计数归零,其他线程才能获得锁。

典型场景:在递归函数中保护一个共享资源。

#include <iostream>
#include <mutex>
#include <thread>
std::recursive_mutex rec_mtx;
int shared_data = 0;
void recursive_function(int count) {
    if (count <= 0) return;
    std::lock_guard<std::recursive_mutex> lock(rec_mtx); // 第二次调用时依然可以加锁成功
    shared_data += count;
    std::cout << "Count: " << count << ", Data: " << shared_data << std::endl;
    recursive_function(count - 1); // 递归调用,会再次加锁
}
int main() {
    std::thread t1(recursive_function, 3);
    t1.join();
    return 0;
}

⚠️ 慎用建议:能用 std::mutex 就尽量不用它。因为它的语义更宽松,容易掩盖糟糕的设计。如果发现需要用递归锁,可以优先考虑重构代码,缩小锁的粒度,或者将递归函数拆分为一个公有接口(加锁)和一个私有实现(不加锁)。

3.std::timed_mutex:带超时功能的互斥量

它继承了 std::mutex 的所有功能,并额外提供了两个成员函数,让你可以“有耐心地等待”:

典型场景:避免因某个线程长期占用锁而导致程序卡死,实现优雅的超时重试。

#include <iostream>
#include <mutex>
#include <thread>
#include <chrono>
std::timed_mutex timed_mtx;
void worker() {
    // 尝试等待 100 毫秒去获取锁
    if (timed_mtx.try_lock_for(std::chrono::milliseconds(100))) {
        std::cout << "线程 " << std::this_thread::get_id() << " 获得锁。" << std::endl;
        // 模拟工作
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
        timed_mtx.unlock();
    } else {
        std::cout << "线程 " << std::this_thread::get_id() << " 等待超时,放弃任务。" << std::endl;
    }
}

4.std::recursive_timed_mutex:功能最全的组合体

它兼具 recursive_mutex(可重入)和 timed_mutex(超时)的特性,是功能最完整的互斥量,但也是开销最大的。

总结:如何选择?

这是一个清晰的选择路径:

到此这篇关于C++ 同步机制 std::mutex的实现示例的文章就介绍到这了,更多相关C++ 同步机制 std::mutex内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文