C++线程中几类锁的详解

yizhihongxing

C++线程中几类锁的详解

前言

在多线程编程中,锁是一种重要的同步机制,可以保证多个线程在访问共享资源时的安全性。C++提供了多种类型的锁,本篇文章将对常用的几种锁进行详解。

互斥锁(mutex)

互斥锁是最常用的一种锁,它保证同一时刻只有一个线程可以访问共享资源。当一个线程获得锁时,其他线程将一直等待直到拥有锁的线程释放锁为止。

创建互斥锁

C++标准库提供了std::mutex类实现互斥锁,创建一个互斥锁的方法如下:

std::mutex mutexObj;

加锁和解锁

互斥锁的加锁和解锁操作分别使用std::mutex类的lock()unlock()方法实现:

mutexObj.lock();
// 临界区代码
mutexObj.unlock();

互斥锁示例

下面是一个使用互斥锁保护共享资源的示例,其中共享资源为一个计数器,多个线程分别对计数器进行加一:

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

std::mutex mutexObj;
int count = 0;

void increaseCount()
{
    mutexObj.lock();

    for (int i=0; i<1000; i++) {
        count++;
    }

    mutexObj.unlock();
}

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

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

    std::cout << "count:" << count << std::endl;

    return 0;
}

在上面的示例中,通过互斥锁的加锁和解锁操作保证了count变量的安全性。如果不使用锁,那么多个线程同时访问count变量将会引发数据竞争问题。

递归锁(recursive mutex)

递归锁是一种互斥锁的变体,它允许同一线程多次获得锁而不会引起死锁。当一个线程对已经拥有的锁再次加锁时,递归锁会记录加锁次数,并在解锁时相应的解锁次数。

创建递归锁

C++标准库提供了std::recursive_mutex类实现递归锁,创建一个递归锁的方法如下:

std::recursive_mutex recursiveMutexObj;

加锁和解锁

递归锁的加锁和解锁操作分别使用std::recursive_mutex类的lock()unlock()方法实现。

递归锁示例

下面是一个使用递归锁保护共享资源的示例,其中共享资源为一个计数器,一个线程递归调用函数对计数器进行加一:

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

std::recursive_mutex recursiveMutexObj;
int count = 0;

void increaseCount()
{
    recursiveMutexObj.lock();
    count++;

    if (count < 1000) {
        increaseCount();
    }

    recursiveMutexObj.unlock();
}

int main()
{
    std::thread t1(increaseCount);
    t1.join();

    std::cout << "count:" << count << std::endl;

    return 0;
}

在上面的示例中,通过递归锁的加锁和解锁操作保证了count变量的安全性。虽然increaseCount()方法递归调用了多次,但是由于使用了递归锁,所以不会引起死锁或者其他线程对共享资源的竞争问题。

读写锁(read-write lock)

读写锁是一种特殊的锁,对于共享资源可以允许多个线程同时进行读访问,但是在进行写访问时需要互斥。读写锁可以提高读取操作的并发性,提高程序性能。

创建读写锁

C++标准库提供了std::shared_timed_mutex类实现读写锁,创建一个读写锁的方法如下:

std::shared_timed_mutex rwMutexObj;

读操作

对于读操作,可以使用std::shared_timed_mutex类的lock_shared()方法进行加锁,使用unlock_shared()方法进行解锁:

rwMutexObj.lock_shared();
// 共享资源读取操作
rwMutexObj.unlock_shared();

当多个线程对共享资源进行读操作时,可以用读写锁来提高并发性,示例如下:

读写锁示例

下面是一个使用读写锁保护共享资源的示例,其中共享资源为一个计数器,多个线程可以同时对计数器进行读取,但是对计数器进行写操作时需要互斥:

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

std::shared_timed_mutex rwMutexObj;
int count = 0;

void increaseCount()
{
    rwMutexObj.lock();
    count++;
    rwMutexObj.unlock();
}

void printCount()
{
    rwMutexObj.lock_shared();
    std::cout << "count:" << count << std::endl;
    rwMutexObj.unlock_shared();
}

int main()
{
    std::thread t1(increaseCount);
    std::thread t2(printCount);

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

    return 0;
}

在上面的示例中,通过读写锁的读和写操作,保证了count变量的安全性。由于多个线程可以同时对count变量进行读取,所以使用读写锁可以提高程序的并发性。

总结

本篇文章介绍了C++中常用的锁类型,包括互斥锁、递归锁和读写锁。通过适当的锁机制可以保证多线程访问共享资源的安全性,提高程序的并发性。在实际应用中应根据具体情况选择合适的锁机制,以达到最优的性能和安全性。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++线程中几类锁的详解 - Python技术站

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

相关文章

  • 一起来学习C++的函数指针和函数对象

    标题:一起来学习C++的函数指针和函数对象 介绍 C++ 中的函数指针和函数对象是非常重要的概念,尤其是在面向对象编程中。本文将介绍函数指针和函数对象的概念,并提供一些使用它们的示例。 函数指针 函数指针是指向函数的指针,它可以用来在程序中动态地调用函数。在 C++ 中,函数指针的类型表示为函数的返回值类型和参数类型的组合。例如,以下是一个指向 int 类型…

    C 2023年5月22日
    00
  • C语言中#if的使用详解

    让我详细讲解一下“C语言中#if的使用详解”的完整攻略。 1. #if的基本用法 if指令是C语言中条件编译的一种方式。它的用法如下: #if condition /* some code */ #endif 其中,condition可以是任何能被求值的表达式,通常是宏定义或预定义宏。如果condition为真,该指令中的代码才会被编译,否则该指令中的代码将…

    C 2023年5月23日
    00
  • 深度学习开源框架基础算法之傅立叶变换的概要介绍

    深度学习开源框架基础算法之傅立叶变换的概要介绍 什么是傅立叶变换? 傅立叶变换(Fourier Transform)是一种能够将时域上的信号转换为频域上的信号的数学工具。简单地说,它将一个时域上的波形分解成多个基频分量,每个分量代表着特定频率的振幅。这个过程是通过利用正弦和余弦函数的数学性质完成的。 傅立叶变换在深度学习中的应用 在深度学习中,经常需要对输入…

    C 2023年5月23日
    00
  • C语言驱动开发之内核使用IO/DPC定时器详解

    关于C语言驱动开发之内核使用IO/DPC定时器详解,我可以提供以下完整攻略: 一、概述 在C语言驱动开发中,IO定时器和DPC定时器功能非常重要。使用IO定时器可以实现周期性的输入输出操作,DPC定时器则可以延迟处理某个操作。 二、IO定时器 以下是IO定时器的使用流程: 1.初始化定时器 在驱动程序中,我们需要创建一个定时器对象。其中,ntDelayTim…

    C 2023年5月23日
    00
  • C++简单实现shared_ptr的代码

    实现一个简单的shared_ptr需要考虑以下几个方面: 1.计数器实现:将指针的计数器放在一个自定义类中,当有多个shared_ptr指向同一个对象时,计数器加1;当一个指针被销毁时,计数器减1;当计数器为0时,释放对象所占用的内存。 2.拷贝构造函数和赋值运算符实现:在拷贝构造函数和赋值运算符中,需要将新对象的计数器指向原对象的计数器,使得两个对象指向同…

    C 2023年5月23日
    00
  • OpenCV实现简单摄像头视频监控程序

    下面我将详细讲解OpenCV实现简单摄像头视频监控程序的完整攻略。 1. 安装OpenCV 要实现摄像头视频监控,首先需要安装OpenCV库。可以在官网(https://opencv.org/)下载安装包,也可以通过 pip 命令进行安装: pip install opencv-python 2. 开始编写代码 2.1 导入库并打开摄像头 import cv…

    C 2023年5月23日
    00
  • C++使用递归方法求n阶勒让德多项式完整实例

    C++使用递归方法求n阶勒让德多项式 什么是勒让德多项式 勒让德多项式是一种数学函数,定义在实数上,常用于解决物理学中的问题。它们表示为:$$ P_n(x) = \frac{1}{2^n n!} \frac{d^n}{dx^n} [(x^2 – 1)^n] $$ 其中,n是多项式的阶数。 递归实现n阶勒让德多项式 通过递归实现n阶勒让德多项式,是一种简便的方…

    C 2023年5月22日
    00
  • Android NDK开发(C语言基本数据类型)

    Android NDK开发(C语言基本数据类型)攻略 什么是Android NDK? Android NDK(Native Development Kit)是一个允许您使用C和C++代码在Android设备上开发应用程序的工具集。NDK允许您在Android应用程序中使用底层C和C++代码,从而提高应用程序性能。使用NDK可以实现以下功能: 构建基于C/C+…

    C 2023年5月24日
    00
合作推广
合作推广
分享本页
返回顶部