C++线程学习二(其他线程锁)

1、其他线程锁及其使用


    临界区:Critical_Region
    在同一个线程中,windows的 "相同临界区变量" 代表的临界区的进入可以被多次调用,几次调用就需要几次释放

    recursive_mutex递归独占互斥量
        std::lock_guard<std::recursive_mutex> 

    std::time_mutex:带超时功能的独占互斥量
        // try_lock_for()   等待一段时间,如果超时没拿到锁,或者已经拿到锁了,流程就往下走
        // try_lock_unit()
    std::recursive_time_mutex:带超时功能的独占互斥量
 

首先介绍临界锁的使用

#include <iostream>	
#include <thread>
#include <mutex>
#include <list>                                                                                                                           
//#include "CWinLock.hpp"                                                                                                                                                                                   
#include <windows.h>

using namespace std;

#define  __WINDOWSJQ_   // 定义windows运行环境


class CriticalRegion
{
public:
  CriticalRegion()
  {
#ifdef __WINDOWSJQ_
  InitializeCriticalSection(&m_CSCtrls);
#endif // __WINDOWSJQ_
  }
  ~CriticalRegion()
  {
#ifdef __WINDOWSJQ_	
    DeleteCriticalSection(&m_CSCtrls);
#endif // __WINDOWSJQ_
  }

  // 存数据
  void inMsgRecvQueue()
  {
    for (int i = 0; i < 1000; i++)
	{
	  cout << "input list i:" << i << endl;
#ifdef __WINDOWSJQ_
     //	CWinLock wLock(&m_CSCtrls);
	  EnterCriticalSection(&m_CSCtrls);
	  m_RecvQueue.push_back(i);
	  LeaveCriticalSection(&m_CSCtrls);
#else
      m_Mutex.lock();
      m_RecvQueue.push_back(i);
      m_Mutex.unlock();
#endif
    }
    // doSomething
    // ...
  }
  bool outMsgQueue(int &num)
  {
#ifdef __WINDOWSJQ_
    EnterCriticalSection(&m_CSCtrls);
    if (!m_RecvQueue.empty())
	{
	  num = m_RecvQueue.front();	            // 返回第一个元素,但是不检查元素是否存在;
	  m_RecvQueue.pop_front();				// 移除第一个元素但不反回
	  LeaveCriticalSection(&m_CSCtrls);		//m_Mutex.unlock();
      return true;
    }
    LeaveCriticalSection(&m_CSCtrls);
#else
    m_Mutex.lock();
	if (!m_RecvQueue.empty())
	{
	  num = m_RecvQueue.front();	            // 返回第一个元素,但是不检查元素是否存在;
	  m_RecvQueue.pop_front();				// 移除第一个元素但不反回
	  m_Mutex.unlock();						//m_Mutex.unlock();
      return true;
	}
	m_Mutex.unlock();
#endif // __WINDOWSJQ_
	return false;
  }

  // 取数据
  void outMsgRecvQueue()
  {
    EnterCriticalSection(&m_CSCtrls);
	int num;
	for (int i = 0; i < 1000; i++)
	{
	  if (outMsgQueue(num))
	  {
	    cout << "delet one data" << num << endl;
	  }
	  else
	  {
		cout << "outMsgRecvQueue no data" << endl;
	  }
	}
	cout << "end" << endl;
	LeaveCriticalSection(&m_CSCtrls);
  }
private:
  std::list<int> m_RecvQueue;
  //互斥量
  std::mutex m_Mutex;
#ifdef __WINDOWSJQ_
  // 临界锁,类似于互斥量
  CRITICAL_SECTION m_CSCtrls;
#endif // __WINDOWSJQ__
};
int main()
{

  CriticalRegion CRobj;
  std::thread t1(&CriticalRegion::inMsgRecvQueue, &CRobj);
  std::thread t2(&CriticalRegion::outMsgRecvQueue, &CRobj);
  t1.join();
  t2.join();
  system("pause");
  return 0;
}

 

 

也可以简化临界锁的使用,定义一个CWinLock()函数用于定于与释放临界锁

#include <windows.h>

// 用于自动释放windows下的临界区,防止忘记释放
// RAII类 资源获取即初始化
class CWinLock
{

public:
  CWinLock(CRITICAL_SECTION *pCritical)
  {
    m_pCritical = pCritical;
    EnterCriticalSection(m_pCritical);
  }
  ~CWinLock(CRITICAL_SECTION *pCritical)
  {
    LeaveCriticalSection(m_pCritical);
  }

private:
	CRITICAL_SECTION *m_pCritical;

};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值