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

发布时间:2025-12-09 13:42:30 浏览次数:4

多线程通同步与互斥示例

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

定义临界区使用单锁

#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 methodsResetEvent(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;}

需要做网站?需要网络推广?欢迎咨询客户经理 13272073477