21xrx.com
2025-03-31 14:50:07 Monday
文章检索 我的文章 写文章
C++11线程锁详解
2023-06-28 14:19:18 深夜i     16     0
C++11 线程锁 多线程编程 互斥锁 可重入锁

C++11引入了许多新特性,比如强类型枚举、Lambda表达式、智能指针等等,其中最重要的特性之一就是线程库。线程库提供了一种非常方便的方法来实现并发编程,能够让程序员更容易地编写多线程应用程序。说到多线程编程,我们就要提到锁。锁是管理共享资源访问的一种机制,主要有互斥锁和读写锁两种。本文将详细介绍C++11中线程锁的用法。

一、互斥锁

互斥锁是一种最简单的锁机制,用于协调多个线程对共享资源的访问。当某个线程获取锁时,它就成为了独占锁,其他线程必须等待该线程释放锁之后才能获取锁。在C++11的线程库中,互斥锁的定义如下:

#include <mutex>
std::mutex mtx;

上面的代码定义了一个名为mtx的互斥锁对象。接下来我们来看一下如何使用互斥锁:

#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
void print(int num) {
  mtx.lock();
  std::cout << num << " ";
  mtx.unlock();
}
int main() {
  std::thread th1(print, 1);
  std::thread th2(print, 2);
  std::thread th3(print, 3);
  th1.join();
  th2.join();
  th3.join();
  return 0;
}

上面的代码定义了一个print函数和三个线程。在print函数中,我们先获取锁,然后输出数字,最后释放锁。main函数中我们开启了三个线程分别打印1、2、3三个数字,由于互斥锁的存在,最终的输出结果一定是1 2 3。需要注意的是,若线程获取锁之后发生了异常而没有释放锁,会导致死锁,因此建议使用C++11提供的std::lock_guard将锁封装起来。

二、读写锁

读写锁是一种高效的锁机制,它可以实现读者-写者问题。读者读取共享数据时,不会对数据进行修改,因此可以并发读取;写者修改共享数据时,必须独占锁,其他线程等待。在C++11的线程库中,读写锁的定义如下:

#include <shared_mutex>
std::shared_mutex mtx;
//获取读锁
std::shared_lock<std::shared_mutex> read_lock(mtx);
//获取写锁
std::unique_lock<std::shared_mutex> write_lock(mtx);

上面的代码定义了一个名为mtx的读写锁对象。由于读写锁支持多读者单写者,因此读锁和写锁的获取方式略有不同。我们来看一下如何使用读写锁:

#include <iostream>
#include <thread>
#include <shared_mutex>
std::shared_mutex mtx;
int num = 0;
void read() {
  std::shared_lock<std::shared_mutex> read_lock(mtx);
  std::cout << "read:" << num << std::endl;
}
void write() {
  std::unique_lock<std::shared_mutex> write_lock(mtx);
  num++;
}
int main() {
  std::thread th1(read);
  std::thread th2(read);
  std::thread th3(write);
  th1.join();
  th2.join();
  th3.join();
  return 0;
}

上面的代码定义了一个read函数和一个write函数以及三个线程。在read函数中,我们获取读锁,输出num的值,然后释放读锁。在write函数中,我们获取写锁,将num的值加1,最后释放写锁。main函数中我们开启了两个读线程和一个写线程。由于读写锁的存在,两个读线程可以并行执行,而写线程必须等到前两个线程都执行完毕才能开始执行。需要注意的是,若读写锁的读者数量很多,也会导致写者一直等待,因此需要合理调度线程。

总结

以上就是C++11中线程锁的详细介绍。互斥锁是最基本的锁机制,可用于协调对共享资源的访问;读写锁是一种高效的锁机制,可实现多读者单写者的并发模型。在编写多线程应用程序时,需要合理地使用锁机制来保证线程安全。

  
  

评论区

请求出错了