MFC(2)MFC中使用信号量(semaphore)做线程同步——用户启动子线程打开串口

来源:互联网 发布:网吧吃鸡优化 编辑:程序博客网 时间:2024/05/29 05:58

新建基于对话框的MFC工程,OpenDevice这个类由DLG类调用。(我的平台是:Win7-x64 / VisualStudio 2012 Ultimate)


OpenDevice.h

<span style="font-size:18px;">#pragma onceclass OpenDevice{public:OpenDevice(void);~OpenDevice(void);public:CWinThread *m_pThread;HANDLEm_hCom;HANDLEm_hSemaphore;BOOL SemIncrease(void);BOOL Init(void);BOOL OpenSerial(void);static UINT work_thread(void *args);};</span>

OpenDevice.c

<span style="font-size:18px;">#include "stdafx.h"#include "OpenDevice.h"OpenDevice::OpenDevice(void){m_hCom = NULL;m_hSemaphore = NULL;m_pThread = NULL;}OpenDevice::~OpenDevice(void){if(NULL != m_hCom){CloseHandle(m_hCom);m_hCom = NULL;}if(NULL != m_hSemaphore){CloseHandle(m_hSemaphore);m_hSemaphore = NULL;}}//初始化信号量,创建子线程(创建的时候立即运行)BOOL OpenDevice::Init(void){//创建并初始化信号量m_hSemaphore = CreateSemaphore(NULL, 0, 1, NULL);if(NULL == m_hSemaphore){TRACE(strerror(GetLastError()));return FALSE;}//创建子线程m_pThread = AfxBeginThread(work_thread, this);if(NULL == m_pThread){TRACE(strerror(GetLastError()));return FALSE;}return TRUE;}BOOL OpenDevice::OpenSerial(void){if(NULL == m_hSemaphore){return FALSE;}//等待串口设备插入:当用户点击打开按钮时,增加信号量的值,则WaitForSingleObject返回//并且减少一个值;然后去打开设备文件,失败后则重新阻塞等待信号量有效。while(1){TRACE("wait for semaphore...\n");DWORD res = WaitForSingleObject(m_hSemaphore, INFINITE);//wait 相当于 信号量的P操作if(WAIT_OBJECT_0 != res){TRACE(strerror(GetLastError()));continue;}//打开串口文件m_hCom = CreateFile("COM3",GENERIC_WRITE | GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0);if(INVALID_HANDLE_VALUE == m_hCom){TRACE(strerror(GetLastError()));AfxMessageBox("串口打开失败!");}else{TRACE("open successful\n");return TRUE;}}}UINT OpenDevice::work_thread(void *args){OpenDevice *pOpenDevice = (OpenDevice *)args;BOOL res = pOpenDevice->OpenSerial();if(TRUE == res){while(1){TRACE("read and write serial!\n");Sleep(5000);}}return 0;}//信号量的V操作BOOL OpenDevice::SemIncrease(void){if(NULL == m_hSemaphore){return FALSE;}BOOL res = ReleaseSemaphore(m_hSemaphore, 1, NULL);if(0 == res){TRACE(strerror(GetLastError()));return FALSE;}return TRUE;}</span>


按钮响应函数:

void CsemaphoreDlg::OnBnClickedOpen(){// TODO: 在此添加控件通知处理程序代码m_openDevice.SemIncrease();}



MFC中信号量的操作和linux中的信号量操作基本相同,只是linux中单独有函数做PV操作。

0 0
原创粉丝点击