当前位置:首页 > 科技  > 软件

C++多线程中的互斥锁

来源: 责编: 时间:2024-06-24 09:11:39 283观看
导读在多线程编程中,互斥锁(mutex)是确保线程安全、避免数据竞争的重要工具。C++标准库提供了多种互斥锁,每种都有其特定的应用场景和特点。主要有以下几种互斥锁(Mutex):std::mutex:最基本的互斥锁,用于保护临界区,确保同一时间只

在多线程编程中,互斥锁(mutex)是确保线程安全、避免数据竞争的重要工具。C++标准库提供了多种互斥锁,每种都有其特定的应用场景和特点。nOH28资讯网——每日最新资讯28at.com

nOH28资讯网——每日最新资讯28at.com

主要有以下几种互斥锁(Mutex):nOH28资讯网——每日最新资讯28at.com

  • std::mutex:最基本的互斥锁,用于保护临界区,确保同一时间只有一个线程可以访问被保护的资源。
  • std::timed_mutex:支持超时机制的互斥锁,可以尝试在给定时间内锁定互斥锁。如果在指定时间内没有成功获取锁,则返回失败。
  • std::recursive_mutex:递归互斥锁,同一线程可以多次获取锁而不会发生死锁,通常用于递归函数中。
  • std::recursive_timed_mutex:支持超时机制的递归互斥锁,结合了递归锁和超时锁的特性。
  • std::shared_mutex(C++17 引入):允许多个线程同时读取,但只有一个线程可以写入。适用于读多写少的场景。
  • std::shared_timed_mutex(C++17 引入):支持超时机制的共享互斥锁,可以在给定时间内尝试获取读锁或写锁。

这些是C++标准库中提供的几种主要的互斥锁类型。每种锁都有其特定的应用场景和使用方法,选择合适的互斥锁类型对于实现高效、安全的多线程程序非常重要。nOH28资讯网——每日最新资讯28at.com

一、基本互斥锁(std::mutex)

std::mutex是最基本的互斥锁,主要用于保护临界区,确保同一时间只有一个线程可以访问共享资源。nOH28资讯网——每日最新资讯28at.com

特点:nOH28资讯网——每日最新资讯28at.com

  • 简单易用,适用于大多数场景。
  • 不能递归锁定,同一线程多次尝试锁定会导致死锁。

示例代码:nOH28资讯网——每日最新资讯28at.com

#include <iostream>#include <thread>#include <mutex>std::mutex mtx;void print_thread_id(int id) {    std::lock_guard<std::mutex> lock(mtx); // 自动管理锁的获取和释放    std::cout << "Thread ID: " << id << std::endl;}int main() {    std::thread t1(print_thread_id, 1);    std::thread t2(print_thread_id, 2);    t1.join();    t2.join();    return 0;}

nOH28资讯网——每日最新资讯28at.com

二、带超时机制的互斥锁(std::timed_mutex)

std::timed_mutex在std::mutex的基础上增加了超时功能,允许线程在指定时间内尝试获取锁,如果在超时时间内未成功获取锁,则返回失败。nOH28资讯网——每日最新资讯28at.com

特点:nOH28资讯网——每日最新资讯28at.com

  • 适用于需要设置锁获取超时时间的场景。
  • 提供try_lock_for和try_lock_until两种超时尝试获取锁的方法。

示例代码:nOH28资讯网——每日最新资讯28at.com

#include <iostream>#include <thread>#include <mutex>#include <chrono>std::timed_mutex tmtx;void try_to_lock(int id) {    if(tmtx.try_lock_for(std::chrono::milliseconds(100))) {        std::cout << "Thread " << id << " locked the mutex" << std::endl;        std::this_thread::sleep_for(std::chrono::milliseconds(200));        tmtx.unlock();    } else {        std::cout << "Thread " << id << " could not lock the mutex" << std::endl;    }}int main() {    std::thread t1(try_to_lock, 1);    std::thread t2(try_to_lock, 2);    t1.join();    t2.join();    return 0;}

nOH28资讯网——每日最新资讯28at.com

三、递归互斥锁(std::recursive_mutex)

std::recursive_mutex允许同一线程多次获取锁而不会发生死锁,这对于递归函数或需要多次锁定的场景非常有用。nOH28资讯网——每日最新资讯28at.com

特点:nOH28资讯网——每日最新资讯28at.com

  • 适用于递归调用和需要多次锁定的场景。
  • 需要注意避免滥用,因为递归锁的使用会增加锁定次数的复杂性。

示例代码:nOH28资讯网——每日最新资讯28at.com

#include <iostream>#include <thread>#include <mutex>std::recursive_mutex rmtx;void recursive_function(int depth) {    rmtx.lock();    std::cout << "Depth: " << depth << std::endl;    if (depth > 0) {        recursive_function(depth - 1);    }    rmtx.unlock();}int main() {    std::thread t(recursive_function, 5);    t.join();    return 0;}

nOH28资讯网——每日最新资讯28at.com

四、带超时机制的递归互斥锁(std::recursive_timed_mutex)

std::recursive_timed_mutex结合了std::recursive_mutex和std::timed_mutex的特性,支持递归锁定和超时机制。nOH28资讯网——每日最新资讯28at.com

特点:nOH28资讯网——每日最新资讯28at.com

  • 适用于递归调用和需要超时机制的场景。
  • 提供超时尝试获取递归锁的方法。

示例代码:nOH28资讯网——每日最新资讯28at.com

#include <iostream>#include <thread>#include <mutex>#include <chrono>std::recursive_timed_mutex rtmmtx;void try_recursive_lock(int id, int depth) {    if (rtmmtx.try_lock_for(std::chrono::milliseconds(100))) {        std::cout << "Thread " << id << " locked at depth " << depth << std::endl;        std::this_thread::sleep_for(std::chrono::milliseconds(50));        if (depth > 0) {            try_recursive_lock(id, depth - 1);        }        rtmmtx.unlock();    } else {        std::cout << "Thread " << id << " could not lock at depth " << depth << std::endl;    }}int main() {    std::thread t1(try_recursive_lock, 1, 3);    std::thread t2(try_recursive_lock, 2, 3);    t1.join();    t2.join();    return 0;}

nOH28资讯网——每日最新资讯28at.com

五、共享互斥锁(std::shared_mutex)

std::shared_mutex允许多个线程同时读取,但只有一个线程可以写入。这在读多写少的场景下非常有用。nOH28资讯网——每日最新资讯28at.com

特点:nOH28资讯网——每日最新资讯28at.com

  • 适用于读多写少的场景。
  • 读操作和写操作使用不同的锁定机制。

示例代码:nOH28资讯网——每日最新资讯28at.com

#include <iostream>#include <thread>#include <shared_mutex>std::shared_mutex shmtx;void read_shared(int id) {    std::shared_lock<std::shared_mutex> lock(shmtx); // 共享锁    std::cout << "Thread " << id << " is reading" << std::endl;    std::this_thread::sleep_for(std::chrono::milliseconds(100));}void write_shared(int id) {    std::unique_lock<std::shared_mutex> lock(shmtx); // 独占锁    std::cout << "Thread " << id << " is writing" << std::endl;    std::this_thread::sleep_for(std::chrono::milliseconds(100));}int main() {    std::thread readers[5], writer(write_shared, 1);    for (int i = 0; i < 5; ++i) {        readers[i] = std::thread(read_shared, i + 2);    }    writer.join();    for (auto& reader : readers) {        reader.join();    }    return 0;}

nOH28资讯网——每日最新资讯28at.com

六、带超时机制的共享互斥锁(std::shared_timed_mutex)

std::shared_timed_mutex结合了std::shared_mutex和std::timed_mutex的特性,支持超时机制。nOH28资讯网——每日最新资讯28at.com

特点:nOH28资讯网——每日最新资讯28at.com

  • 适用于读多写少且需要超时机制的场景。
  • 提供超时尝试获取共享锁的方法。

示例代码:nOH28资讯网——每日最新资讯28at.com

#include <iostream>#include <thread>#include <shared_mutex>#include <chrono>std::shared_timed_mutex shtmmtx;void try_read_shared(int id) {    if (shtmmtx.try_lock_shared_for(std::chrono::milliseconds(100))) {        std::cout << "Thread " << id << " is reading" << std::endl;        std::this_thread::sleep_for(std::chrono::milliseconds(50));        shtmmtx.unlock_shared();    } else {        std::cout << "Thread " << id << " could not read" << std::endl;    }}void try_write_shared(int id) {    if (shtmmtx.try_lock_for(std::chrono::milliseconds(100))) {        std::cout << "Thread " << id << " is writing" << std::endl;        std::this_thread::sleep_for(std::chrono::milliseconds(50));        shtmmtx.unlock();    } else {        std::cout << "Thread " << id << " could not write" << std::endl;    }}int main() {    std::thread readers[5], writer(try_write_shared, 1);    for (int i = 0; i < 5; ++i) {        readers[i] = std::thread(try_read_shared, i + 2);    }    writer.join();    for (auto& reader : readers) {        reader.join();    }    return 0;}

nOH28资讯网——每日最新资讯28at.com

总结

C++标准库提供了多种类型的互斥锁,每种锁都有其特定的用途和特点。选择合适的互斥锁类型可以有效提高程序的并发性能和安全性。nOH28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-95917-0.htmlC++多线程中的互斥锁

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Go 1.23:拥抱iter包,简化你的迭代逻辑

下一篇: C++ vs Rust vs Go 性能比较

标签:
  • 热门焦点
  • K6:面向开发人员的现代负载测试工具

    K6 是一个开源负载测试工具,可以轻松编写、运行和分析性能测试。它建立在 Go 和 JavaScript 之上,它被设计为功能强大、可扩展且易于使用。k6 可用于测试各种应用程序,包括 Web
  • 2023 年的 Node.js 生态系统

    随着技术的不断演进和创新,Node.js 在 2023 年达到了一个新的高度。Node.js 拥有一个庞大的生态系统,可以帮助开发人员更快地实现复杂的应用。本文就来看看 Node.js 最新的生
  • 如何正确使用:Has和:Nth-Last-Child

    我们可以用CSS检查,以了解一组元素的数量是否小于或等于一个数字。例如,一个拥有三个或更多子项的grid。你可能会想,为什么需要这样做呢?在某些情况下,一个组件或一个布局可能会
  • JavaScript学习 -AES加密算法

    引言在当今数字化时代,前端应用程序扮演着重要角色,用户的敏感数据经常在前端进行加密和解密操作。然而,这样的操作在网络传输和存储中可能会受到恶意攻击的威胁。为了确保数据
  • 19个 JavaScript 单行代码技巧,让你看起来像个专业人士

    今天这篇文章跟大家分享18个JS单行代码,你只需花几分钟时间,即可帮助您了解一些您可能不知道的 JS 知识,如果您已经知道了,就当作复习一下,古人云,温故而知新嘛。现在,我们就开始今
  • 自律,给不了Keep自由!

    来源 | 互联网品牌官作者 | 李大为编排 | 又耳 审核 | 谷晓辉自律能不能给用户自由暂时不好说,但大概率不能给Keep自由。近日,全球最大的在线健身平台Keep正式登陆港交所,努力
  • 携众多高端产品亮相ChinaJoy,小米带来一场科技与人文的视听盛宴

    7月28日,全球数字娱乐领域最具知名度与影响力的年度盛会中国国际数码互动娱乐展览会(简称ChinaJoy)在上海新国际博览中心盛大开幕。作为全球领先的科
  • 8月见!小米MIX Fold 3获得3C认证:支持67W快充

    这段时间以来,包括三星、一加、荣耀等等有不少品牌旗下的最新折叠屏旗舰都得到了不少爆料,而小米新一代折叠屏旗舰——小米MIX Fold 3此前也屡屡被传
  • 信通院:小米、华为等11家应用商店基本完成APP签名及验签工作

    中国信通院表示,目前,小米、华为、OPPO、vivo、360手机助手、百度手机助手、应用宝、豌豆荚和努比亚等9家应用商店,以及抖音和快手2家新型应用分发平
Top