MFC(3) 继续有趣的实验——CWinThread类中的唤醒和休眠来操作子线程

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;
	}

	<span style="color:#ff6666;">//创建子线程(创建的时候挂起,不立即运行)
	m_pThread = AfxBeginThread(work_thread, this, 0, 0, CREATE_SUSPENDED, 0);</span>
	//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;
	}

	
	while(1)
	{
		TRACE("wait for semaphore...\n");

#if 0
		DWORD res = WaitForSingleObject(m_hSemaphore, INFINITE);				//wait 相当于 信号量的P操作
		if(WAIT_OBJECT_0 != res)
		{
			TRACE(strerror(GetLastError()));
			
			continue;
		}
#endif
		TRACE("start CreateFile...\n");
		//打开串口文件
		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("串口打开失败!");

			<span style="color:#ff6666;">//挂起当前线程
			m_pThread->SuspendThread();</span>
		}
		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>


按钮响应函数:

<span style="font-size:18px;">void CsemaphoreDlg::OnBnClickedOpen()
{
	// TODO: 在此添加控件通知处理程序代码
	//m_openDevice.SemIncrease();

	//唤醒子线程
	m_openDevice.m_pThread->ResumeThread();

}</span>

由此可见:MFC中的CWinThread这个类已经实现了线程同步的功能。

那么既然信号量可以实现,事件event也应该可以实现同步。


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