C++多线程编程中的锁详解

在现代软件开发中,多线程编程是提升应用程序性能和响应能力的重要手段。然而,多线程编程也带来了数据竞争和死锁等复杂问题。为了确保线程间的同步和共享数据的一致性,C++标准库提供了多种锁机制。

1. std::mutex

std::mutex是最基础的互斥锁,用于保护共享数据,防止多个线程同时访问该数据。

cpp 复制代码
#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;

void print_thread_id(int id) {
    mtx.lock();
    std::cout << "Thread " << id << std::endl;
    mtx.unlock();
}

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

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

    return 0;
}

在上述代码中,mtx.lock()和mtx.unlock()分别用于加锁和解锁,确保同一时刻只有一个线程可以访问临界区(std::cout操作)。

2. std::recursive_mutex

std::recursive_mutex允许同一线程多次获得同一锁,而不会导致死锁。适用于递归调用中需要加锁的场景。

cpp 复制代码
#include <iostream>
#include <thread>
#include <mutex>

std::recursive_mutex rec_mtx;

void recursive_function(int count) {
    if (count <= 0) return;
    rec_mtx.lock();
    std::cout << "Count: " << count << std::endl;
    recursive_function(count - 1);
    rec_mtx.unlock();
}

int main() {
    std::thread t(recursive_function, 5);
    t.join();

    return 0;
}

3. std::timed_mutex

std::timed_mutex支持尝试在一定时间内获取锁。这在避免死锁和提高程序响应性方面很有用。

cpp 复制代码
#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>

std::timed_mutex tmtx;

void try_lock_for_example() {
    if (tmtx.try_lock_for(std::chrono::seconds(1))) {
        std::cout << "Lock acquired" << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(2));
        tmtx.unlock();
    } else {
        std::cout << "Failed to acquire lock" << std::endl;
    }
}

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

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

    return 0;
}

4. std::recursive_timed_mutex

std::recursive_timed_mutex结合了std::recursive_mutex和std::timed_mutex的特性

cpp 复制代码
#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>

std::recursive_timed_mutex rtmtx;

void recursive_timed_function(int count) {
    if (count <= 0) return;
    if (rtmtx.try_lock_for(std::chrono::seconds(1))) {
        std::cout << "Count: " << count << std::endl;
        recursive_timed_function(count - 1);
        rtmtx.unlock();
    } else {
        std::cout << "Failed to acquire lock" << std::endl;
    }
}

int main() {
    std::thread t(recursive_timed_function, 5);
    t.join();

    return 0;
}

5. std::shared_mutex(C++17引入)

std::shared_mutex允许多个线程同时读取共享数据,但只允许一个线程写入数据。这种机制适用于读多写少的场景。

cpp 复制代码
#include <iostream>
#include <thread>
#include <shared_mutex>

std::shared_mutex smtx;

void read_function() {
    smtx.lock_shared();
    std::cout << "Reading data" << std::endl;
    smtx.unlock_shared();
}

void write_function() {
    smtx.lock();
    std::cout << "Writing data" << std::endl;
    smtx.unlock();
}

int main() {
    std::thread t1(read_function);
    std::thread t2(read_function);
    std::thread t3(write_function);

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

    return 0;
}

6. std::shared_timed_mutex(C++14引入)

std::shared_timed_mutex结合了std::shared_mutex和std::timed_mutex的特性。

cpp 复制代码
#include <iostream>
#include <thread>
#include <shared_mutex>
#include <chrono>

std::shared_timed_mutex stmtx;

void shared_timed_read_function() {
    if (stmtx.try_lock_shared_for(std::chrono::seconds(1))) {
        std::cout << "Reading data" << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(2));
        stmtx.unlock_shared();
    } else {
        std::cout << "Failed to acquire shared lock" << std::endl;
    }
}

void shared_timed_write_function() {
    if (stmtx.try_lock_for(std::chrono::seconds(1))) {
        std::cout << "Writing data" << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(2));
        stmtx.unlock();
    } else {
        std::cout << "Failed to acquire exclusive lock" << std::endl;
    }
}

int main() {
    std::thread t1(shared_timed_read_function);
    std::thread t2(shared_timed_read_function);
    std::thread t3(shared_timed_write_function);

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

    return 0;
}

7. std::lock_guard

std::lock_guard提供一种异常安全的方式来管理锁的生命周期,通常用于自动解锁。

cpp 复制代码
#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;

void lock_guard_example() {
    std::lock_guard<std::mutex> lock(mtx);
    std::cout << "Lock acquired using lock_guard" << std::endl;
    // mtx is automatically unlocked when lock goes out of scope
}

int main() {
    std::thread t(lock_guard_example);
    t.join();

    return 0;
}

8. std::unique_lock

std::unique_lock比std::lock_guard更加灵活,支持延迟加锁、解锁和重新加锁。

cpp 复制代码
#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;

void unique_lock_example() {
    std::unique_lock<std::mutex> lock(mtx);
    std::cout << "Lock acquired using unique_lock" << std::endl;
    lock.unlock();
    std::cout << "Lock released" << std::endl;
    lock.lock();
    std::cout << "Lock reacquired" << std::endl;
}

int main() {
    std::thread t(unique_lock_example);
    t.join();

    return 0;
}

9. std::shared_lock(C++17引入)

std::shared_lock用于管理共享互斥量(std::shared_mutex或std::shared_timed_mutex),提供了一种简单的方式来处理读锁。

cpp 复制代码
#include <iostream>
#include <thread>
#include <shared_mutex>

std::shared_mutex smtx;

void shared_lock_example() {
    std::shared_lock<std::shared_mutex> lock(smtx);
    std::cout << "Shared lock acquired" << std::endl;
}

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

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

    return 0;
}

结论

C++标准库提供了多种锁机制,帮助开发者在多线程环境中确保数据的一致性和线程的同步。根据具体的应用场景选择合适的锁,可以有效地避免数据竞争和死锁问题,从而编写出高效、安全的多线程程序。

相关推荐
半杯咖啡半行码2 小时前
C++ 编程与 STL 模板:从泛型编程到内存安全详解
开发语言·c++
xh didida3 小时前
Linux -- 基础IO
linux·服务器·开发语言·c++
垆边人似月.3 小时前
华为机试题 :两数之和
c++·算法·华为
个 人 练 习 生3 小时前
C++ string 类模拟实现:从底层理解字符串(上)
开发语言·c++·经验分享·学习·程序人生
垆边人似月.3 小时前
华为机试题 :有效的括号
c++·算法·华为
坤坤子吖3 小时前
C++智能指针:RAII、shared_ptr与内存泄漏
开发语言·c++·笔记·学习
神仙别闹4 小时前
基于C++实现的贪吃蛇游戏平台
java·c++·游戏
王老师青少年编程4 小时前
2026年6月GESP真题及题解(C++三级): 选择题和判断题(题解)
c++·真题·gesp·答案·csp·三级·信奥赛
C++ 老炮儿的技术栈4 小时前
static的作用
c语言·c++·人工智能·单片机·c
程序员老陆6 小时前
C++ 未定义行为全景:对象模型、优化边界与工程防御
开发语言·c++·程序设计