关键词:
一、基本概念
1、互斥量(mutex)
互斥量:是个类对象(可以理解为一把锁),多个线程尝试用lock()成员函数来加锁这把锁,只有一个线程能锁定成功(成功的标志是lock()函数能够返回,返回不了说明没有锁成功)
2、死锁
死锁:一般是两个或两个以上的互斥量,在两个或多个地方上锁的顺序不一致导致的互相等待的情况
死锁解决方法:保证每个地方,互斥量上锁的顺序一致
二、样例
1、多线程加锁的例子
class MyClass // 模拟给一个消息队列发消息和处理消息 public: void WriteMessage() // 模拟发消息,也就是往消息队列中写 for (int i = 0; i < 10000; ++i) cout << "插入一个元素:" << i << endl; m_mutex.lock(); // lock() 与 unlock() 要成对使用 m_messages.push_back(i); m_mutex.unlock(); //void ReadMessage() // 模拟处理消息队列中的消息,从中读,也删除 // // for (int i = 0; i < 10000; ++i) // // if (!m_messages.empty()) // 用到共享数据m_messages 的地方都要加锁 // // int i = m_messages.front(); // 用到共享数据m_messages 的地方都要加锁 // cout << "读取的数据为:" << i << endl; // 此处不需要加锁,只加锁需要加锁的部分,提高程序效率 // m_messages.pop_front(); // 用到共享数据m_messages 的地方都要加锁 // // else // // cout << "目前消息队列为空" << i << endl; // // // // 上面的函数优化后的结果 // 把需要加锁的代码专门提取出来 // 只对需要加锁的代码加锁,操作共享数据的部分 bool IsMessagesListEmpty(int& iCount) m_mutex.lock(); if(!m_messages.empty()) iCount = m_messages.front(); m_messages.pop_front(); m_mutex.unlock(); // 每条分支语句都要unlock return true; m_mutex.unlock(); // 每条分支语句都要unlock return false; void ReadMessage() // 模拟处理消息队列中的消息,从中读,也删除 int iCount = 0; for (int i = 0; i < 10000; ++i) if (IsMessagesListEmpty(i)) cout << "读取的数据为:" << i << endl; else cout << "目前消息队列为空" << i << endl; private: list<int> m_messages; // 模拟消息队列 mutex m_mutex; // 创建一个互斥量成员对象 ; int main() MyClass ele; std::thread writeThread(&MyClass::WriteMessage, &ele); // std::thread readThread(&MyClass::ReadMessage, &ele); // readThread.join(); writeThread.join(); cout << "主线程" << endl; system("pause"); return 0;
2、lock_guard
//std::lock_guard 相当于lock和unlock std::lock_guard<std::mutex> myLockGuard(m_mutex); // myLockGuard构造的时候执行mutex::lock // myLockGuard析构的时候执行mutex::unlock // 可以通过加 来控制lock_guard 的生存周期,从而达到随时加锁,随时解锁的目的
3、std::lock
// 解决死锁的方法,保证上锁的顺序一致 // 也可以用std::lock() 来对多个锁进行加锁 // std::lock() 可以同时锁住两个或两个以上的互斥量 // 它不存在在多线程中,因为锁的顺序问题,而导致的死锁问题 // 要么其中的互斥量都锁住,要么都没锁住,不会锁住其中一个,而去等另外一个 // 也就是说,如果其中有一个锁已经被锁住了,它需要等所有的锁都能上锁的状态,才能加锁,继续往下执行 // 示例: std::lock(m_mutex1, m_mutex2) // 上锁一起上 m_mutex1.unlock(); // 解锁还是需要自己解锁 m_mutex2.unlock();
4、结合std::lock() 和lock_guard
// 结合lock_guard 和 std::lock 达到不需要手动unlock() 的效果 std::lock(m_mutex1, m_mutex2) std::lock_guard<std::mutex> myLockGuard(m_mutex1, std::adopt_lock); std::lock_guard<std::mutex> myLockGuard(m_mutex2, std::adopt_lock); // std::adopt_lock 的作用是让 lock_guard 在构造的时候,不执行lock() // 因为在std::lock()中已经执行了lock()
多线程安全问题(代码片段)
多线程访问共享数据会产生安全问题,比如下面的案例,创建了三个线程,访问共享的数据,会出现安全问题Runable实现类当ticket的值大于0,run方法里输出ticket的值packagecn.zhuobo.day12.aboutMultithreading;publicclassRunableImplimplementsRunnablepr... 查看详情
线程安全(代码片段)
1、线程安全:多线程单线程程序运行结果一致线程不安全:多线程单线程程序运行结果不一致2、导致线程安全问题原因全局变量或者静态变量引起;一般情况下,多个线程只读数据,不写数据,则线程是安全的;若多个线程同... 查看详情
多线程共享数据(代码片段)
多个线程行为一致共同操作一个数据,最经典的例子就是卖票publicclassShareDataprivateintnum=10;publicsynchronizedvoidinc()num++;System.out.println(Thread.currentThread().getName()+"调用inc这个方法num="+num);tryThread.sleep(1000) 查看详情
java多线程编程——多线程技能(代码片段)
第一章Java多线程技能文章目录第一章Java多线程技能前言一、进程和多线程概述二、使用多线程1.继承Thread类2.线程随机性的展现3.实现Runnable接口4.使用Runnable接口实现多线程的优点5.实例变量共享造成的非线程安全问题与解决方... 查看详情
线程的同步(解决多线程安全问题)(代码片段)
多线程出现安全问题的原因:当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有 执行完,另一个线程参与进来执行。导致共享数据的错误。 解决方法: 对多条操作共... 查看详情
高并发多线程基础之线程间通信与数据共享及其应用(代码片段)
前言本篇文章主要介绍的是java多线程之间如何通信,协同处理任务,以及数据共享,定时任务处理等操作。多线程之间通信的方式在实际开发过程中多个线程同时操作,有两种情况的,数据共享和线程间协作... 查看详情
rust多线程之数据共享(代码片段)
1.怎么创建线程我们都知道Java中通过实现Runnable接口或继承Thread类,来完成一个线程的创建,那么在Rust中是如何实现一个线程的呢?代码如下。fnhow_to_create_a_thread() //创建一个线程letthread_handle=thread::spawn(||println!(... 查看详情
个人笔记--多线程(安全和通信)(代码片段)
线程安全问题:由于多个线程在操作共享数据,且多条语句对共享数据进行运算,所以产生了多线程安全问题,从而有了同步代码块。同步的前提:至少两个线程。必须保证是使用同一个锁。补充:多次start()同一个线程是非法... 查看详情
多线程(代码片段)
1线程同步1.1线程安全 java允许多线程并发控制,当多个线程同时操作一个可共享资源变量时(如对其进行增删改查操作),会导致数据不准确,而且相互之间产生冲突。所以加入同步锁以避免该线程在没有操作完共享资源前... 查看详情
多线程安全问题
------------恢复内容开始------------一、线程中安全问题产生的原因。1、多个线程在操作共享数据。2、操作共享数据的线程代码有多条。当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算,就会导致线程安全... 查看详情
从零开始学java-day17(代码片段)
多线程编程的两种实现方式extendsThread优点:缺点:后续变化小,局限性大implementRunnable优点:多实现,更加灵活且解耦缺点:写法相对复杂,一些资源需要借助Thread多线程数据安全隐患怎么产生?线程的随机性+访问延迟以后如... 查看详情
java多线程编程——多线程技能(代码片段)
第一章Java多线程技能文章目录第一章Java多线程技能前言一、进程和多线程概述二、使用多线程1.继承Thread类2.线程随机性的展现3.实现Runnable接口4.使用Runnable接口实现多线程的优点5.实例变量共享造成的非线程安全问题与解决方... 查看详情
线程同步机制。(代码片段)
---恢复内容开始---线程安全问题:概述:场景:电影院有一百张票,现在用一个窗口卖1-100号票,属于单线程问题,无线程安全问题 现在有两个窗口,分别卖1-50和51-100号票,属于多线程问题,因为没有访问共享数 ... 查看详情
7.2.4-并发多线程互斥锁(代码片段)
一互斥锁进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的,而共享带来的是竞争,竞争带来的结果就是错乱,如下frommultiprocessingimportProcess,Lockimporttimedeftask(name):print("%s1"%name)time... 查看详情
java面试题多线程-线程安全(代码片段)
面试题:Java是如何解决线程安全问题的,有几种方式?并对比几种方式的不同方式一:同步代码块synchronized(同步监视器=对象)//需要被同步的代码说明:操作共享数据的代码,即为需要被同步的代码。--... 查看详情
线程数据共享和安全-threadlocal(代码片段)
ThreadLocal线程数据共享和安全-ThreadLocal概述代码示例源码分析大家好呀,我是小笙!这部分是我学习ThreadLocal的笔记线程数据共享和安全-ThreadLocal概述ThreadLocal是一个将在多线程中为每一个线程创建单独的变量副本的类;当... 查看详情
python多进程和多线程的使用(代码片段)
...参数args和kwargs5.进程之间不共享全局变量6.守护进程7.多线程7.1线程介绍7.2多线程实现方式8.线程的无序执行9.守护线程10.线程之间共享全局变量11.线程共享全局变量出现的问题12.线程同步13.互斥锁14.解释一下互斥锁产生的死锁问... 查看详情
多线程(代码片段)
1.进程VS线程2.创建多线程-threading3.创建多线程-Thread子类4.同步5.死锁6.生产者与消费者模式 1.进程VS线程定义进程是资源分配的最小单位,线程是CPU调度的最小单位。一个程序启动后至少有一个进程,一个进程至少有一个... 查看详情