【语言-C++】多线程通同步 临界区 CCriticalSection 与 CSingleLock

原创 2017年01月03日 17:39:14

多线程通同步与互斥示例

下面示例是一个相机处理和显示分开的两个线程:

定义临界区使用单锁

#define _CRITICAL_LOCK(critical_lock)			CSingleLock locker(&critical_lock);	locker.Lock();
CCriticalSection _critical_data2;

启动线程,创建四个事件:停止线程事件、处理图像事件、显示图像事件和接收图像事件

停止线程事件:线程接受自动复位 ,初始状态为无信号状态;控制两个线程同时结束

处理图像事件:手动复位,初始状态为无信号状态;

显示图像事件:手动复位,初始状态为无信号状态;

接收图像事件:手动复位,初始状态为有信号状态;

处理图像事件和显示图像事件同时发生时,激活图像处理线程,进行图像处理;接收图像事件的时间的触发由显示图像完成后触发;处理图像事件由相机线程图像传输来触发;

显示图像事件发生时激活显示图像线程进行图像处理。

创建线程

void CMainDlgEx::StartThread()
{
	m_EventStop			= CreateEvent(NULL,TRUE,FALSE,NULL);
	m_EventDealImage		= CreateEvent(NULL,FALSE,FALSE,NULL);
	m_EventImageShow		 = CreateEvent(NULL,FALSE,FALSE,NULL);
	m_EventAllowReceiveImage = CreateEvent(NULL,FALSE,TRUE,NULL);
	// auxiliary methods
	ResetEvent(m_EventStop);
	SetEvent(m_EventAllowReceiveImage);
	// 启动三个线程 
	m_HTDealImage = (HANDLE)_beginthreadex(NULL,								
		0,								
		(unsigned (__stdcall *)(void*))	&Thread_DealImage,
		this,					
		0,					
		&m_IDDealImage);			

	m_HTShowImage = (HANDLE)_beginthreadex(NULL,					
		0,					
		(unsigned (__stdcall *)(void*))&Thread_ShowImage,	
		this,					
		0,					
		&m_IDShowImage);					
}


关闭线程

void CMainDlgEx::CloseThread()
{  
	SetEvent(m_EventStop);       
	WaitForSingleObject(m_HTShowImage,INFINITE);
	WaitForSingleObject(m_HTDealImage,INFINITE);
	if (m_EventStop!=NULL &&m_EventStop !=INVALID_HANDLE_VALUE)
		CloseHandle(m_EventStop);
	if (m_EventDealImage!=NULL &&m_EventDealImage !=INVALID_HANDLE_VALUE)
		CloseHandle(m_EventDealImage);
	if (m_EventAllowReceiveImage!=NULL &&m_EventAllowReceiveImage !=INVALID_HANDLE_VALUE)
		CloseHandle(m_EventAllowReceiveImage );
	if (m_EventImageShow!=NULL &&m_EventImageShow !=INVALID_HANDLE_VALUE)
		CloseHandle(m_EventImageShow);
	DeleteCriticalSection(&m_DealImageMutex);
}


处理线程

void Thread_DealImage(LPVOID *lpParam)
{
	OutputDebugString(_T("处理中 ....启动\n"));
	HANDLE      eventHandle[2];
	CMainDlgEx *MultiThrDlg = (CMainDlgEx*) lpParam;	

	eventHandle[0] = (*MultiThrDlg).m_EventAllowReceiveImage; 
	eventHandle[1] = (*MultiThrDlg).m_EventDealImage;  

	while (WAIT_OBJECT_0 != WaitForSingleObject((MultiThrDlg->m_EventStop),0))
	{
		//抓取数据到grabData中
		while (WAIT_OBJECT_0 == WaitForMultipleObjects(2,eventHandle,TRUE,0))
		{
			_CRITICAL_LOCK(_critical_data2);
			OutputDebugString(_T("处理中 ....\n"));
			SetEvent(MultiThrDlg->m_EventImageShow);
		}
	}
	ResetEvent(MultiThrDlg->m_EventDealImage);
	ResetEvent(MultiThrDlg->m_EventAllowReceiveImage);
	OutputDebugString(_T("处理中 ....退出\n"));
	return;
}


显示线程

extern void Thread_ShowImage( LPVOID *lpParam )
{
	HANDLE      eventHandle[2];
	CMainDlgEx *MultiThrDlg = (CMainDlgEx*) lpParam;	
	OutputDebugString(_T("显示中 ....启动\n"));
	while (WAIT_OBJECT_0 != WaitForSingleObject((MultiThrDlg->m_EventStop),0))
	{
		//抓取数据到grabData中
		while (WAIT_OBJECT_0 == WaitForSingleObject((MultiThrDlg->m_EventImageShow),0))
		{
			_CRITICAL_LOCK(_critical_data2);
			OutputDebugString(_T("显示中 ....\n"));
			SetEvent(MultiThrDlg->m_EventAllowReceiveImage);
		}
	}
	ResetEvent(MultiThrDlg->m_EventImageShow);
	ResetEvent(MultiThrDlg->m_EventAllowReceiveImage);
	OutputDebugString(_T("显示中 ....退出\n"));
	return;
}

数据到达

LRESULT CMainDlgEx::OnCameraDataArrive(WPARAM w, LPARAM l)	
{
	SetEvent(m_EventDealImage);
	return -1;
}




版权声明:本文为博主原创文章,未经博主允许不得转载。

CCriticalSection与CSingleLock

CCriticalSection An object of class CCriticalSection represents a “critical section” — a synchron...
  • Gordennizaicunzai
  • Gordennizaicunzai
  • 2017年12月26日 22:36
  • 79

CSingleLock使用方法

先上实例代码: class CDataArray { private: int iArray[10]; CMutex Mutex; CCriticalSection CritSe...
  • u012372584
  • u012372584
  • 2017年04月11日 15:34
  • 1664

C++ 临界区 多线程同步互斥

临界区(Critical Section) 保证在某一时刻只有一个线程能访问数据的简便办法。在任意时刻只允许一个线程对共享资源进行访问。如果有多个线程试图同时访问临界区,那么在有一个线 程进入后其他所...
  • lzg13541043726
  • lzg13541043726
  • 2014年07月17日 11:29
  • 7890

C++多线程实例之临界区同步

临界区的特点:非内核对象,只能在window下使用,linux下不能使用;只能在同一进程内的线程间使用,速度快。 互斥量特点:互斥量是内核对象,可以用于进程内也可以在进程间互斥,速度相对互斥量慢点,也...
  • Blues1021
  • Blues1021
  • 2015年03月22日 09:51
  • 1992

关于CRITICAL_SECTION、CCriticalSection和信号量的问题

CRITICAL_SECTION cs;EnterCriticalSection(&cs);LeaveCriticalSection(&cs);和CCr...
  • benny5609
  • benny5609
  • 2008年01月25日 09:48
  • 2519

windows核心编程-关键段(临界区)线程同步

windows核心编程-关键段(临界区)线程同步 线程同步的方式主要有:临界区、互斥区、事件、信号量四种方式。 接下来我主要讲一下自己在学习windows核心编程中对于临界区线程同步方式的使用。 临界...
  • windows_nt
  • windows_nt
  • 2013年05月20日 23:54
  • 6364

C++多线程同步(采用关键代码段即临界区)

C++多线程同步(采用关键代码段即临界区)
  • hk627989388
  • hk627989388
  • 2016年11月25日 14:51
  • 799

多线程(c++11)------线程同步

多线程能提高程序的效率,但同时也带来了相应的问题----数据竞争。当多个线程同时操作同一个变量时,就会出现数据竞争。出现数据竞争,一般会用临界区(Critical Section)、互斥量(Mutex...
  • u012085988
  • u012085988
  • 2014年03月29日 22:44
  • 1639

MFC线程同步—— CCriticalSection类使用

多个线程访问临界区时,可以使用临界区对象。临界区对象是一个独占性共享资源,任一时刻只有一个线程可以拥有临界区。拥有临界区的线程可以访问被保护起来的资源或代码段,其他希望进入临界区的线程将被挂起等待,直...
  • qq_24343479
  • qq_24343479
  • 2016年11月15日 22:40
  • 408

windows多线程同步机制---临界区

临界区      临界区作用     线程在执行代码时,将代码锁定,不允许其他线程执行,只有该线程离开后, 其他线程才能使用这些代码  临界区的使用     2.1 初始化临界区   ...
  • rankun1
  • rankun1
  • 2016年02月16日 21:33
  • 524
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【语言-C++】多线程通同步 临界区 CCriticalSection 与 CSingleLock
举报原因:
原因补充:

(最多只允许输入30个字)