C++11各种锁的具体使用

yizhihongxing

C++11各种锁的具体使用

在多线程编程时,锁是常用的线程同步机制之一。C++11中提供了多种不同的锁类型,用于处理不同的并发情况,本文将详细介绍这些锁的用法。

1、互斥锁(std::mutex

使用互斥锁可以实现对共享资源的互斥访问。

#include <iostream>
#include <mutex>
#include <thread>
#include <vector>

std::mutex mtx; //定义互斥锁对象

void func(int id)
{
    for(int i = 0; i < 5; ++i)
    {
        mtx.lock(); //获取互斥锁
        std::cout << "Thread " << id << " : " << i << std::endl;
        mtx.unlock(); //释放互斥锁
    }
}

int main()
{
    std::vector<std::thread> ths;
    for(int i = 1; i <= 5; ++i)
    {
        ths.emplace_back(func, i);
    }

    for(auto& th : ths)
    {
        th.join();
    }

    return 0;
}

输出:

Thread 1 : 0
Thread 1 : 1
Thread 1 : 2
Thread 1 : 3
Thread 1 : 4
Thread 3 : 0
Thread 3 : 1
Thread 3 : 2
Thread 3 : 3
Thread 3 : 4
Thread 2 : 0
Thread 2 : 1
Thread 2 : 2
Thread 2 : 3
Thread 2 : 4
Thread 4 : 0
Thread 4 : 1
Thread 4 : 2
Thread 4 : 3
Thread 4 : 4
Thread 5 : 0
Thread 5 : 1
Thread 5 : 2
Thread 5 : 3
Thread 5 : 4

在函数func中,使用互斥锁对cout流实现了互斥访问,从而避免线程之间的竞争。

2、递归互斥锁(std::recursive_mutex

递归互斥锁和普通互斥锁一样,它也可以保证对共享资源的互斥访问,但它允许同一线程多次获取互斥锁而不会死锁。

#include <iostream>
#include <mutex>
#include <vector>

std::recursive_mutex rmtx;

int recur(int n)
{
    if(n <= 1)
        return 1;
    rmtx.lock();
    int ret = n * recur(n - 1);
    rmtx.unlock();
    return ret;
}

int main()
{
    std::vector<std::thread> ths;
    for(int i = 1; i <= 5; ++i)
    {
        ths.emplace_back([i](){
            std::cout << "Thread " << i << ": " << recur(5) << std::endl;
        });
    }

    for(auto& th : ths)
    {
        th.join();
    }

    return 0;
}

输出:

Thread 1: 120
Thread 2: 120
Thread 3: 120
Thread 4: 120
Thread 5: 120

在递归函数recur中,使用了递归互斥锁,允许同一线程多次获取互斥锁。

3、共享锁(std::shared_mutex

共享锁用于读写分离场景,多个线程可以同时持有共享锁(共享访问),但只有一个线程可以持有独占锁(排它访问)。

#include <iostream>
#include <shared_mutex>
#include <thread>
#include <vector>

std::shared_mutex smtx;

void read_func(int id)
{
    smtx.lock_shared();
    std::cout << "Thread " << id << ": read" << std::endl;
    smtx.unlock_shared();
}

void write_func(int id)
{
    smtx.lock();
    std::cout << "Thread " << id << ": write" << std::endl;
    smtx.unlock();
}

int main()
{
    std::vector<std::thread> ths;
    for(int i = 1; i <= 5; ++i)
    {
        if(i % 2 == 0)
            ths.emplace_back(write_func, i);
        else
            ths.emplace_back(read_func, i);
    }

    for(auto& th : ths)
    {
        th.join();
    }

    return 0;
}

输出:

Thread 1: read
Thread 3: read
Thread 5: read
Thread 2: write
Thread 4: write

在函数read_func中,使用共享锁对cout流实现了共享访问,在函数write_func中,使用共享锁对cout流实现了排它访问。

4、条件变量锁(std::condition_variable

条件变量锁允许一个线程等待另一个线程满足特定条件时被唤醒。

#include <iostream>
#include <mutex>
#include <condition_variable>
#include <thread>

std::mutex mtx;
std::condition_variable cv;
bool flag = false;

void func1()
{
    std::unique_lock<std::mutex> lock(mtx);
    std::cout << "func1 start" << std::endl;
    flag = true;
    lock.unlock();
    cv.notify_one();
}

void func2()
{
    std::unique_lock<std::mutex> lock(mtx);
    while(!flag)
    {
        cv.wait(lock); //等待条件变量
    }
    std::cout << "func2 start" << std::endl;
}

int main()
{
    std::thread t1(func1);
    std::thread t2(func2);
    t1.join();
    t2.join();

    return 0;
}

输出:

func1 start
func2 start

在函数func1中,改变了全局变量flag的值,并使用了条件变量通知线程func2,从而被唤醒。

以上就是C++11各种锁的详细介绍及对应的示例代码。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++11各种锁的具体使用 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • C++实现图书管理系统(文件操作与类)

    C++ 实现图书管理系统(文件操作与类) 背景 现在很多图书馆、书店、个人的藏书、电子图书馆等都需要一个可以管理图书的系统,对于这样的需求,我们可以使用 C++ 语言来实现。 本文将会介绍如何使用 C++ 实现一个图书管理系统,并使用文件操作和面向对象的方式来进行数据保存和管理。 思路 我们需要实现一个图书管理系统,这个系统应该包含以下功能: 添加图书 删除…

    C 2023年5月24日
    00
  • 打印圣诞树

    打印圣诞树 今天遇到一个不算特别变态的题目,可是却往错误的方向思考了有一会儿。 这是这个题目的链接:[打印圣诞树](圣诞树_牛客题霸_牛客网 (nowcoder.com)) 题目大致意思是,给定一个高度,打印出圣诞树。 效果图类似以下这种: 错误示范 首先我把每片叶子看作是5X3的矩形,空白看作是3X3的矩形。 最上面为第1层,最下面为第n层。 第i层前面有…

    C语言 2023年4月17日
    00
  • Win8.1系统在SSD盘安装双系统提示错误代码0xc0000225的故障原因及解决方法

    Win8.1系统在SSD盘安装双系统提示错误代码0xc0000225的故障原因及解决方法 故障原因 当我们在一个SSD盘上安装Win8.1系统的双系统时,有时会遇到以下错误提示: Windows 启动管理器 Windows 检测到计算机的启动配置数据(BCD)缺少必要的文件。 文件位于:»\Windows\system32\winload.efi 错误代码:…

    C 2023年5月24日
    00
  • C++基本算法思想之递推算法思想

    C++基本算法思想之递推算法思想 什么是递推算法 递推算法又称为递归算法,是常用于求解问题的一种算法思想。它通过求出问题的一个基本情况,然后通过逐步迭代、递推,从而得到问题的一个规模更大的解。通俗的说,就是将一个大问题分解成多个相对较小的问题,通过依次解决每个小问题最终得到大问题的解。 如何实现递推算法 递推算法可以通过编写递归代码进行实现,也可以通过循环实…

    C 2023年5月22日
    00
  • C语言实现图书馆管理系统

    C语言实现图书馆管理系统攻略 背景介绍 随着图书馆图书数量的不断增加,传统的人工管理方式已经越来越难以适应现代的需求,因此,采用计算机辅助手段实现图书馆管理是一个非常好的选择。下面我们将介绍如何使用C语言来实现一个图书馆管理系统。 系统功能 本系统主要包括以下功能: 图书信息的添加、删除、修改、查询 借书、还书功能 统计信息的查询 用户信息的添加、删除、修改…

    C 2023年5月23日
    00
  • BYC币怎么样?BYC/币缘币还值得投资吗

    BYC币的基本概念 BYC币,全名为币缘币(Bytecoin),是一种匿名、去中心化、开源的数字货币。它于2012年创立,是第一代公开发行的隐私币之一。相比于比特币,BYC币主张保护交易者的隐私,并提供更快的交易确认速度和更低的交易费用。 BYC币的投资价值分析 优点 高度保护隐私:BYC币使用了加密技术和混淆账户的方法,可以有效保护交易者的个人隐私。 去中…

    C 2023年5月23日
    00
  • win2008 R2服务器下修改MySQL 5.5数据库data目录的方法

    修改MySQL 5.5数据库data目录的方法需要按照以下步骤进行。 步骤1:备份原有数据 在修改数据目录之前,首先需要备份原有数据。可以使用mysqldump命令,将原有数据导出到其他文件或目录中。 示例: mysqldump -u root -p dbname > dbname.sql 以上命令中,-u 参数指定用户名,-p 参数后面跟着密码,db…

    C 2023年5月22日
    00
  • FTP客户端c代码功能实现

      现在市面上有很多免费的FTP软件:如FileZilla ,那如果想自己在代码中实现与ftp服务器的上传下载文件该如何实现那?  本质上ftp协议就是TCP基础上建立的一种协议,具体如下。 FTP 概述 文件传输协议(FTP)作为网络共享文件的传输协议,在网络应用软件中具有广泛的应用。FTP的目标是提高文件的共享性和可靠高效地传送数据。 在传输文件时,FT…

    C语言 2023年4月18日
    00
合作推广
合作推广
分享本页
返回顶部