首页 > 编程语言 >C++ thread 互斥操作

C++ thread 互斥操作

时间:2023-10-04 11:22:56浏览次数:30  
标签:std thread lock 解锁 C++ 互斥 num mutex include

Thread Mutex

  • std::mutex 是 C++11 最基本的互斥量,该类的实例化对象提供了资源独占所有权的特性,用于保护共享数据免受多个线程同时访问的同步原语。

Mutex

用法

  1. 头文件
    • #include<mutex>
  2. 类型
    • std::mutex
      • 最基础的 Mutex 类
    • std::recursive_mutex
      • 递归的 Mutex 类
    • std::time_mutex
      • 定时 Mutex
    • std::recursive_time_mutex
      • 定时递归 Mutex 类
  3. 操作
    • 加锁
      • lock
    • 解锁
      • unlock
    • 查看是否上锁
      • trylock
      • 未上锁,返回 false,并锁住
      • 其他线程已上锁,返回 true
      • 同一线程已经上锁,将会产生死锁

代码

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

using namespace std;
int g_resource_printer = 4;
mutex mx;

void person_1()
{
    mx.lock();
    g_resource_printer++;
    this_thread::sleep_for(chrono::seconds(2));
    cout << "Thread_1 using printer.... g_resource_printer : " << g_resource_printer << endl;
    mx.unlock();
}

void person_2()
{
    mx.lock();
    g_resource_printer--;
    this_thread::sleep_for(chrono::seconds(2));
    cout << "Thread_2 Using printer.... g_resource_printer : " << g_resource_printer << endl;
    mx.unlock(); 
}

int main()
{
    thread thread1(person_1);
    thread thread2(person_2);

    thread1.join();
    thread2.join();

    return 0;
}

lock_gurad

介绍

  • 会在实例化时去获取一个 mutex 的所有权,在作用域消失时,会自动析构并释放 mutex
  • 创建即加锁,作用域结束自动析构并解锁,无需自动解锁
  • 不能中途解锁,也不支持手动解锁
  • 不能复制

代码

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

using namespace std;

mutex g_mtx;
int g_resource = 1;

void proc_1()
{
    lock_guard<mutex> lk(g_mtx);
    // the code for handling shared resources
    g_resource++;
    cout << "Proc 1 : " << g_resource << endl;
}

void proc_2()
{
    lock_guard<mutex> lk(g_mtx);
    g_resource--;
    cout << "Proc 2 : " << g_resource << endl;

}

int main()
{
    thread thread1(proc_1);
    thread thread2(proc_2);

    thread1.join();
    thread2.join();

    return 0;
}

unique_lock

介绍

  • 创建时可以不锁定,在需要的再锁定
  • 可以手动的,随时加锁解锁
  • 作用域结束后,析构函数自动释放锁
  • 不可复制,可移动
  • 条件变量需要该类型的锁作为参数(此时必须使用 unique_lock)

代码

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

struct Box
{
    explicit Box(int num) : num_thing(num){}
    int num_thing;
    std::mutex m;
};

void transfer(Box& from, Box &to, int num)
{
    // std::defer_lock means locks later
    std::unique_lock<std::mutex> lock1(from.m, std::defer_lock);
    std::unique_lock<std::mutex> lock2(to.m, std::defer_lock);
	
    std::lock(lock1, lock2);	// now lock lock1 and lock2
	// lock1.lock()
	// lock2.lock()

    from.num_thing -= num;
    to.num_thing += num;
}

int main()
{
    Box acc1(100);
    Box acc2(200);

    std::thread thread1(transfer, std::ref(acc1), std::ref(acc2), 10);
    std::thread thread2(transfer, std::ref(acc1), std::ref(acc2), 20);
    thread1.join();
    thread2.join();

    std::cout << "acc1.num_thing : " << acc1.num_thing << std::endl;
    std::cout << "acc2.num_thing : " << acc2.num_thing << std::endl;

    return 0;
}

总结:

  1. 为了解决多线程资源竞争,C++ 使用 mutex 类提供数据保护
  2. 为了践行RAII思想,或者说为了防止加锁后忘记解锁,使用 lock_guard
  3. 为了更方便的使用锁,提供 unique_lock 即保证了 RAII,又可以手动解锁

标签:std,thread,lock,解锁,C++,互斥,num,mutex,include
From: https://www.cnblogs.com/wanghao-boke/p/17742043.html

相关文章

  • 关于Actor Component的思考--学习斯坦佛UE+C++
    跟着B站的视频学习,感觉自己的头很混乱。所以浅浅总结一下创建ActorComponent之后其的作用和相关操作。ActorComponent首先Component为一个组件,源码就是一个类的声明和类的实现。所以对其的操作就是对类的操作。可以在其源码内部定义一些物体属性,比如一个角色的Component。我们......
  • 十四天学会C++之第二天(函数和库)
    1.函数的定义和调用在C++中,函数是组织和结构化代码的关键工具之一。它们允许您将一段代码封装成一个可重复使用的模块,这有助于提高代码的可读性和维护性。为什么使用函数?函数在编程中的作用不可小觑。它们有以下几个重要用途:模块化编程:函数允许将代码划分为小的、独立的单元,使得......
  • C++ Thread 基础使用
    C++11Thread使用基础用法头文件#include<thread>函数初始化threadthread(<function_name>);线程分离thread.detach();线程阻塞thread.join()线程取消this_thread::yield();线程休眠this_thread::sleep_for(chrono::seconds(3));代码#in......
  • C++特种成员函数生成机制及相关原则
    C++特种成员函数生成机制及相关原则注:默认C++标准是C++11及以后的标准,因为C++11之前的标准定义的默认成员函数不包含移动构造函数和移动赋值运算符1.C++默认成员函数默认成员函数的定义:类中没有显示声明,在需要时由编译器自动生成的函数,包括默认构造函数、默认析构函数、......
  • 基于hash_table对STL unordered系列容器的封装 #C++
    概述本文对hash_table进行封装,以模仿SGISTL对unordered系列容器进行简单实现,旨在加深对C++封装与泛型技法的体会与理解。阅读本文之前,建议先对哈希表进行学习。unordered_map与map一样,unordered_map的所有元素类型都是pair,pair的第一个成员为Key,第二个成员为Value。因为Key在任何......
  • 第8期ThreadX视频教程:应用实战,将裸机工程移植到RTOS的任务划分,驱动和应用层交互,中断DM
    视频教程汇总帖:https://www.armbbs.cn/forum.php?mod=viewthread&tid=110519 这个是我们初学RTOS面临的最直接问题,很多时候,简单的RTOS机制明白了,API也会调用了,就是添加到RTOS后,总感觉那里不对劲,怎么使用才是正确姿势。针对这些问题,本期视频教程,我们ThreadX内核教程穿插一期实......
  • C++ 对拍详解 和解读
    对拍是什么#​对拍,是一个比较实用的工具。它能够非常方便地对于两个程序的输出文件进行比较,可以帮助我们实现一些自动化的比较输出结果的问题。​众所周知,几乎每一道编程题目,都会有某种正解能拿到满分;当我们想不出正解时,我们往往可以打暴力代码来获取部分分数。​但是,当我们觉......
  • C++类内存分布+ Studio工具
    书上类继承相关章节到这里就结束了,这里不妨说下C++内存分布结构,我们来看看编译器是怎么处理类成员内存分布的,特别是在继承、虚函数存在的情况下。工欲善其事,必先利其器,我们先用好VisualStudio工具,像下面这样一步一步来:  先选择左侧的C/C++->命令行,然后在其他选项这里写上......
  • C++ STL快速入门方法
    在数月之前的机试中第一次体验到STL的威力,因为自己本来一直在用C语言做开发,很多数据结构都是自己造的,比如链表、队列等,第一次接触C++STL后发现这些数据结构都已经给我提供好了,我直接拿去调用就好了,真是超级方便。最近的项目中也遇到了STL一些容器,所以现在自己好好总结一下STL中......
  • C++模板元编程(C++ template metaprogramming)
    实验平台:Win7,VS2013Community,GCC4.8.3(在线版) 所谓元编程就是编写直接生成或操纵程序的程序,C++模板给C++语言提供了元编程的能力,模板使C++编程变得异常灵活,能实现很多高级动态语言才有的特性(语法上可能比较丑陋,一些历史原因见下文)。普通用户对C++模板的使用可能不是很......