上一篇博文:

https://blog.csdn.net/qq78442761/article/details/81276366

这里有一点:

CRITICAL_SECTION

此玩意,类似于互斥锁,是Windows平台提供的。

程序运行截图如下:

源码如下:

DeadLock.h

#pragma once#include <windows.h>
#include <iostream>
using namespace std;#define PRODUCERCNT 1   //生产者线程数量
#define CONSUMERCNT 1   //消费者线程数量
#define TOTALCNT PRODUCERCNT+CONSUMERCNTclass CDeadLock
{
public:CDeadLock();~CDeadLock();void CreateThread();void ToggleStatus();private:HANDLE hConsole;    //控制台句柄-改变控制台颜色输出bool m_bRunning;   //通知线程需要关闭int m_buffer; //关键数据-临界资源HANDLE threads[TOTALCNT];    //保存所有线程句柄static DWORD WINAPI producer(LPARAM lParam);  //生产者线程函数static DWORD WINAPI consumer(LPARAM lParam);   //消费者线程函数//生产和消费动作void produce();void consume();//Windows中提供了关键段,来协调CRITICAL_SECTION m_cs;
};

DeadLock.cpp

#include "DeadLock.h"CDeadLock::CDeadLock()
{hConsole = INVALID_HANDLE_VALUE;m_bRunning = false;m_buffer = 0;for (int i = 0; i < TOTALCNT; i++) {threads[i] = INVALID_HANDLE_VALUE;}hConsole = GetStdHandle(STD_OUTPUT_HANDLE);SetConsoleTitle(L"死锁");InitializeCriticalSection(&m_cs);
}CDeadLock::~CDeadLock()
{CloseHandle(hConsole);for (int i = 0; i < TOTALCNT; i++) {if (threads[i] != INVALID_HANDLE_VALUE) {CloseHandle(threads[i]);}}DeleteCriticalSection(&m_cs);
}void CDeadLock::CreateThread()
{int i = 0;m_bRunning = true;for (; i < PRODUCERCNT; i++) {threads[i] = ::CreateThread(0, 0, (LPTHREAD_START_ROUTINE)producer, this, 0, 0);}for (i = 0; i < CONSUMERCNT; i++) {threads[i] = ::CreateThread(0, 0, (LPTHREAD_START_ROUTINE)consumer, this, 0, 0);}
}void CDeadLock::ToggleStatus()
{m_bRunning = !m_bRunning;
}//生产者线程
DWORD WINAPI CDeadLock::producer(LPARAM lParam)
{CDeadLock *pThis = (CDeadLock*)lParam;cout << "producer threadID:" << GetCurrentThreadId() << endl;while (pThis->m_bRunning) {EnterCriticalSection(&pThis->m_cs);SetConsoleTextAttribute(pThis->hConsole, FOREGROUND_RED);pThis->produce();LeaveCriticalSection(&pThis->m_cs);}return 0;
}//消费者线程
DWORD WINAPI CDeadLock::consumer(LPARAM lParam)
{CDeadLock *pThis = (CDeadLock*)lParam;cout << "consumer threadID:" << GetCurrentThreadId() << endl;while (pThis->m_bRunning) {Sleep(10);EnterCriticalSection(&pThis->m_cs);SetConsoleTextAttribute(pThis->hConsole, FOREGROUND_GREEN);pThis->consume();LeaveCriticalSection(&pThis->m_cs);}return 0;
}void CDeadLock::produce()
{if (m_buffer > 200) {return;}//m_buffer++;__asm {mov         eax, dword ptr[this] //取this指针mov         ecx, dword ptr[eax + 8]   //取m_buffer的值,放在ecx寄存器里面//有可能执行到这一步,发送时间片到期的状态... 如果是10,那么这个10已经到了ecx寄存器里面,//这时候,消费者开始消耗了,消费者消耗完后应该是9,//但是,这个时候生产者的时间片又到了,此时把寄存器++,变成了11,这样就有问题了!!!add         ecx, 1                   //ECX++mov         edx, dword ptr[this]   //取this指针//此处可以直接这么优化 mov dword prt[eax+8],ecxmov         dword ptr[edx + 8], ecx //再放回去}printf("生产 - %d\n", m_buffer);
}void CDeadLock::consume()
{int data = m_buffer--;if (data) {printf("消费 - %d\n", data);}
}

main.cpp

#include "DeadLock.h"
#include <conio.h>void main() {cout << "main called!\n";CDeadLock deadLock;deadLock.CreateThread();   //注意,如果CreateThread两次,那么以前的线程就会被抛弃掉cout << "press any key to exit ... \n";while (true) {char cmd = _getch();if (cmd == 'q') {break;}else if (cmd == 'n') {deadLock.ToggleStatus();}}
}

认识死锁之生产者与消费者相关推荐

  1. java多线程(同步和死锁,生产者和消费者问题)

    首先我们来看看同步与死锁: 所谓死锁.这是A有banana,B有apple. A至B说:你把apple对我来说,,我会banana给你. B至A说:你把banana对我来说,,我会apple给你. 可 ...

  2. 操作系统之进程管理:12、生产者消费者问题和多级生产者多级消费者问题

    12.生产者消费者问题和多级生产者多级消费者问题 生产者消费者问题 1.问题描述 2.解题思路 3.解题过程 4.问题 多级生产者多级消费者问题 1.问题描述 2.解题思路 3.解题过程: 4.问题 ...

  3. JAVA笔记14__多线程共享数据(同步)/ 线程死锁 / 生产者与消费者应用案例 / 线程池...

    /*** 多线程共享数据* 线程同步:多个线程在同一个时间段只能有一个线程执行其指定代码,其他线程要等待此线程完成之后才可以继续执行.* 多线程共享数据的安全问题,使用同步解决.* 线程同步两种方法: ...

  4. 菜鸟学习笔记:Java提升篇8(线程2——线程的基本信息、线程安全、死锁、生产者消费者模式、任务调度)

    菜鸟学习笔记:Java提升篇8(线程2--线程的基本信息.线程安全.死锁.生产者消费者模式.任务调度) 线程的基本信息 线程同步 线程安全 死锁 生产者消费者模式 任务调度(了解) 线程的基本信息 J ...

  5. 多线程:线程同步与死锁(卖票案例)、线程通信、生产者与消费者

    卖票案例 5个窗口同时卖票: 使用Runnable接口,只创建了一个ticket1对象,5个线程共享此对象,实现了资源共享. public class ticket1 implements Runna ...

  6. c/c++:线程同步(互斥锁、死锁、读写锁、条件变量、生产者和消费者模型、信号量)

    目录 1. 概念 2. 互斥锁 3. 死锁 4. 读写锁 5. 条件变量 5.1 生产者和消费者模型 6. 信号量 1. 概念 线程同步: > 当有一个线程在对内存进行操作时,其他线程都不可以对 ...

  7. 【Linux】生产者与消费者模型、信号量、死锁

    目录 死锁 死锁的产生场景 死锁的gdb分析 1.通过调试可执行程序来分析 2.通过调试正在运行的程序 死锁的必要条件 死锁的预防 生产者与消费者模型 123规则 应用场景及特点 代码实现: 信号量 ...

  8. 6※、线程同步、同步锁、同步代码块的使用、同步锁释放的时机、ReentrantLock可重入锁、公平锁与非公平锁的区别、什么是死锁、线程间的通信(生产者和消费者模式)

    线程锁 1.※线程的同步:(要确保对象锁是一致的) 1.未使用同步锁的抢票 2.使用了同步锁的抢票 3.线程-同步代码块的使用 4.同步方法和代码块的区别 5.同步锁释放的时机 练习:多线程生产手机 ...

  9. 笔记-13-多线程 Thread方法 线程安全 生产者和消费者 死锁和阻塞

    1.实现多线程 1.1简单了解多线程[理解] 是指从软件或者硬件上实现多个线程并发执行的技术. 具有多线程能力的计算机因有硬件支持而能够在同一时间执行多个线程,提升性能. 1.2并发和并行[理解] 并 ...

最新文章

  1. Android UI开发神兵利器之Icon
  2. 前馈pid系数_SPMSM控制——基于模型的电流前馈控制及思考
  3. . mybatis指定配置文件的根元素_MyBatis框架
  4. mysql select符合查询_MySQL SELECT 联合查询
  5. 当稳定币遇上BCH,将会擦出什么样的火花?
  6. ASP.NET Core默认注入方式下如何注入多个实现(多种方式) - sky 胡萝卜星星 - CSDN博客...
  7. ios build lame
  8. JavaEE(26) - {TODO}
  9. ajax常用吗,常用ajax请求
  10. magisk核心功能模式是什么_redmi K20pro刷太极·Magisk的心酸历程or教程(附K20pro第三方rec)...
  11. 算命师傅的好帮手:一款简单好用又使用的排盘工具--灵棋排盘
  12. T9 PDF如何转存为高清图片
  13. [案例分享]金融大数据:三大应用场景提升营销收益 (二)
  14. 机器算法基础——回归分析
  15. word双栏左右不能对齐
  16. pinyin4j 中文转成拼音(支持多音字输出)
  17. STM32开发基础知识——定时器
  18. android onkeydown()简介
  19. ! [rejected] Dev-1.1.1 -> Dev-1.1.1 (would clobber existing tag)
  20. 企业应该如何搭建私有云服务器数据中心?需要注意哪些问题

热门文章

  1. 550 5.7.1 Client does not have permissions to send as this sender
  2. 肿瘤坏死因子(TNF)阻断剂治疗幼年型银屑病关节炎: 有效吗
  3. 互联网把农业推向“科技仙境”
  4. 一进庙会freeeim
  5. DirectSound开发
  6. 2020 年最牛逼的 10 门编程语言,别在选错语言了
  7. HTML5设备API 大批美女等你来摇一摇
  8. python获取浏览器数据_python 获取有关访问者的浏览器的 细节
  9. java.io下载_java io 文件下载
  10. 机房布线的最高境界 | 最后的暗黑系,真是亮瞎眼 ​