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

相关推荐
tan77º19 分钟前
【Linux网络编程】Socket - UDP
linux·服务器·网络·c++·udp
GiraKoo1 小时前
【GiraKoo】C++14的新特性
c++
悠悠小茉莉1 小时前
Win11 安装 Visual Studio(保姆教程 - 更新至2025.07)
c++·ide·vscode·python·visualstudio·visual studio
坏柠1 小时前
C++ Qt 基础教程:信号与槽机制详解及 QPushButton 实战
c++·qt
泽02022 小时前
C++之红黑树认识与实现
java·c++·rpc
岁忧2 小时前
(LeetCode 每日一题) 1865. 找出和为指定值的下标对 (哈希表)
java·c++·算法·leetcode·go·散列表
whoarethenext3 小时前
使用 C++ 实现 MFCC 特征提取与说话人识别系统
开发语言·c++·语音识别·mfcc
R-G-B3 小时前
【MFC】Combobox下拉框中4个选项,运行后点击下拉框选项不能全部展示出来,只能显示2个选项,需要垂直滚动条滚动显示其余选项
c++·mfc
视觉人机器视觉5 小时前
Visual Studio2022和C++opencv的配置保姆级教程
c++·opencv·visual studio
liulilittle5 小时前
C++ i386/AMD64平台汇编指令对齐长度获取实现
c语言·开发语言·汇编·c++