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

新建基于对话框的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操作。

你可能感兴趣的:(多线程,windows,Semaphore,mfc)