认识死锁之生产者与消费者
生活随笔
收集整理的這篇文章主要介紹了
认识死锁之生产者与消费者
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
上一篇博文:
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 //生產(chǎn)者線程數(shù)量 #define CONSUMERCNT 1 //消費者線程數(shù)量 #define TOTALCNT PRODUCERCNT+CONSUMERCNTclass CDeadLock { public:CDeadLock();~CDeadLock();void CreateThread();void ToggleStatus();private:HANDLE hConsole; //控制臺句柄-改變控制臺顏色輸出bool m_bRunning; //通知線程需要關(guān)閉int m_buffer; //關(guān)鍵數(shù)據(jù)-臨界資源HANDLE threads[TOTALCNT]; //保存所有線程句柄static DWORD WINAPI producer(LPARAM lParam); //生產(chǎn)者線程函數(shù)static DWORD WINAPI consumer(LPARAM lParam); //消費者線程函數(shù)//生產(chǎn)和消費動作void produce();void consume();//Windows中提供了關(guān)鍵段,來協(xié)調(diào)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; }//生產(chǎn)者線程 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寄存器里面//有可能執(zhí)行到這一步,發(fā)送時間片到期的狀態(tài)... 如果是10,那么這個10已經(jīng)到了ecx寄存器里面,//這時候,消費者開始消耗了,消費者消耗完后應(yīng)該是9,//但是,這個時候生產(chǎn)者的時間片又到了,此時把寄存器++,變成了11,這樣就有問題了!!!add ecx, 1 //ECX++mov edx, dword ptr[this] //取this指針//此處可以直接這么優(yōu)化 mov dword prt[eax+8],ecxmov dword ptr[edx + 8], ecx //再放回去}printf("生產(chǎn) - %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();}} }?
總結(jié)
以上是生活随笔為你收集整理的认识死锁之生产者与消费者的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++工作笔记-简单工厂模式基础(用静态
- 下一篇: Qt工作笔记-QSS中关于QScroll