您的位置:首页 > 其它

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

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

OpenDevice.h

<span style="font-size:18px;">#pragma once
class OpenDevice
{
public:
OpenDevice(void);
~OpenDevice(void);

public:
CWinThread *m_pThread;

HANDLE	m_hCom;
HANDLE	m_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操作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐