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

C++多线程中的互斥锁

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

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

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

主要有以下几种互斥锁(Mutex):qgr28资讯网——每日最新资讯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++标准库中提供的几种主要的互斥锁类型。每种锁都有其特定的应用场景和使用方法,选择合适的互斥锁类型对于实现高效、安全的多线程程序非常重要。qgr28资讯网——每日最新资讯28at.com

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

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

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

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

示例代码:qgr28资讯网——每日最新资讯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;}

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

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

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

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

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

示例代码:qgr28资讯网——每日最新资讯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;}

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

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

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

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

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

示例代码:qgr28资讯网——每日最新资讯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;}

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

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

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

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

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

示例代码:qgr28资讯网——每日最新资讯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;}

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

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

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

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

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

示例代码:qgr28资讯网——每日最新资讯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;}

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

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

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

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

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

示例代码:qgr28资讯网——每日最新资讯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;}

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

总结

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

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

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

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

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

标签:
  • 热门焦点
  • 红魔电竞平板评测:大屏幕硬实力

    前言:三年的疫情因为要上网课的原因激活了平板市场,如今网课的时代已经过去,大家的生活都恢复到了正轨,这也就意味着,真正考验平板电脑生存的环境来了。也就是面对着这种残酷的
  • Redmi Buds 4开箱简评:才199还有降噪 可以无脑入

    在上个月举办的Redmi Note11T Pro系列新机发布会上,除了两款手机新品之外,Redmi还带来了两款TWS真无线蓝牙耳机产品,Redmi Buds 4和Redmi Buds 4 Pro,此前我们在Redmi Note11T
  • 从 Pulsar Client 的原理到它的监控面板

    背景前段时间业务团队偶尔会碰到一些 Pulsar 使用的问题,比如消息阻塞不消费了、生产者消息发送缓慢等各种问题。虽然我们有个监控页面可以根据 topic 维度查看他的发送状态,
  • JavaScript学习 -AES加密算法

    引言在当今数字化时代,前端应用程序扮演着重要角色,用户的敏感数据经常在前端进行加密和解密操作。然而,这样的操作在网络传输和存储中可能会受到恶意攻击的威胁。为了确保数据
  • 在线图片编辑器,支持PSD解析、AI抠图等

    自从我上次分享一个人开发仿造稿定设计的图片编辑器到现在,不知不觉已过去一年时间了,期间我经历了裁员失业、面试找工作碰壁,寒冬下一直没有很好地履行计划.....这些就放在日
  • 只需五步,使用start.spring.io快速入门Spring编程

    步骤1打开https://start.spring.io/,按照屏幕截图中的内容创建项目,添加 Spring Web 依赖项,并单击“生成”按钮下载 .zip 文件,为下一步做准备。请在进入步骤2之前进行解压。图
  • 最“俊美”淘宝卖家,靠直播和短视频圈粉,上架秒光,年销3000万

    来源 | 电商在线文|易琬玉编辑|斯问受访店铺:Ringdoll戒之人形图源:微博@御座的黄山、&ldquo;Ringdoll戒之人形&rdquo;淘宝店铺有关外貌的评价,黄山已经听累了。生于1985年的他,哪
  • 腾讯VS网易,最卷游戏暑期档,谁能笑到最后?

    作者:无锈钵来源:财经无忌7月16日晚,上海1862时尚艺术中心。伴随着幻象的精准命中,硕大的荧幕之上,比分被定格在了14:12,被寄予厚望的EDG战队以绝对的优势战胜了BLG战队,拿下了总决
  • 东方甄选单飞:有些鸟注定是关不住的

    作者:彭宽鸿来源:华尔街科技眼&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;东方甄选创始人俞敏洪带队的&ldquo;7天甘肃行&rdquo;直播活动已在近日顺利收官。成立后一
Top