📄 theade~2.cpp
字号:
// TheadExp2Dlg.cpp : 实现文件
//
#include "stdafx.h"
#include "TheadExp2.h"
#include "TheadExp2Dlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// 对话框数据
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CTheadExp2Dlg 对话框
CTheadExp2Dlg::CTheadExp2Dlg(CWnd* pParent /*=NULL*/)
: CDialog(CTheadExp2Dlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CTheadExp2Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_THREAD1, m_BeginTh1);
DDX_Control(pDX, IDC_END_THREAD1, m_EndTh1);
DDX_Control(pDX, IDC_THREAD2, m_BeginTh2);
DDX_Control(pDX, IDC_END_THREAD2, m_EndTh2);
}
BEGIN_MESSAGE_MAP(CTheadExp2Dlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_THREAD1, OnBnClickedThread1)
ON_BN_CLICKED(IDC_END_THREAD1, OnBnClickedEndThread1)
ON_BN_CLICKED(IDC_THREAD2, OnBnClickedThread2)
ON_BN_CLICKED(IDC_END_THREAD2, OnBnClickedEndThread2)
ON_BN_CLICKED(IDC_RADIO_MUTEX, OnBnClickedRadioMutex)
ON_BN_CLICKED(IDC_RADIO_SEMAPHORES, OnBnClickedRadioSemaphores)
ON_BN_CLICKED(IDC_RADIO_CRITICAL, OnBnClickedRadioCritical)
ON_BN_CLICKED(IDC_EXIT, OnBnClickedExit)
END_MESSAGE_MAP()
// CTheadExp2Dlg 消息处理程序
BOOL CTheadExp2Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 将\“关于...\”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO:在此添加额外的初始化代码
//存储对话框窗口句柄
hDlg=GetSafeHwnd();
//使用于终止线程的按钮无效
m_EndTh1.EnableWindow(FALSE);
m_EndTh2.EnableWindow(FALSE);
//默认的同步方法为使用列界区对象
g_Sel=0;
((CButton *)GetDlgItem(IDC_RADIO_CRITICAL))->SetCheck(1);
return TRUE; // 除非设置了控件的焦点,否则返回 TRUE
}
void CTheadExp2Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CTheadExp2Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标显示。
HCURSOR CTheadExp2Dlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CTheadExp2Dlg::OnBnClickedThread1()
{
// TODO: 在此添加控件通知处理程序代码
//使【开始线程1】按钮无效,同时使【终止线程1】按钮有效
m_BeginTh1.EnableWindow(FALSE);
m_EndTh1.EnableWindow(TRUE);
//标识第一个线程开始
g_Th1End=FALSE;
//使选择同步方法按钮无效
EnableSelection(FALSE);
//使第一线程的事件对象处于无信号状态
g_EndTh1.ResetEvent();
//启动第一个线程,用于写数据
AfxBeginThread(ThreadProcWt,GetSafeHwnd());
}
void CTheadExp2Dlg::OnBnClickedEndThread1()
{
// TODO: 在此添加控件通知处理程序代码
//使【开始线程1】按钮有效,同时使【终止线程1】按钮无效
m_BeginTh1.EnableWindow(TRUE);
m_EndTh1.EnableWindow(FALSE);
//标识第一个线程结束
g_Th1End=TRUE;
//使选择同步方法按钮有效
EnableSelection(TRUE);
//使第一线程的事件对象处于有信号状态
g_EndTh1.SetEvent();
}
void CTheadExp2Dlg::OnBnClickedThread2()
{
// TODO: 在此添加控件通知处理程序代码
m_BeginTh2.EnableWindow(FALSE);
m_EndTh2.EnableWindow(TRUE);
g_Th2End=FALSE;
EnableSelection(FALSE);
g_EndTh2.ResetEvent();
//启动第二个线程,用于读数据
AfxBeginThread(ThreadProcRd,GetSafeHwnd());
}
void CTheadExp2Dlg::OnBnClickedEndThread2()
{
// TODO: 在此添加控件通知处理程序代码
m_BeginTh2.EnableWindow(TRUE);
m_EndTh2.EnableWindow(FALSE);
g_Th2End=TRUE;
EnableSelection(TRUE);
g_EndTh2.SetEvent();
}
void CTheadExp2Dlg::EnableSelection(BOOL end)
{
if(end==TRUE)
{
//当两个线程都结束时,使选择同步方法按钮有效
if(g_Th1End&g_Th2End)
{
GetDlgItem(IDC_RADIO_CRITICAL)->EnableWindow(TRUE);
GetDlgItem(IDC_RADIO_MUTEX)->EnableWindow(TRUE);
GetDlgItem(IDC_RADIO_SEMAPHORES)->EnableWindow(TRUE);
}
}
//否则,使选择同步方法按钮有效
else
{
GetDlgItem(IDC_RADIO_CRITICAL)->EnableWindow(FALSE);
GetDlgItem(IDC_RADIO_MUTEX)->EnableWindow(FALSE);
GetDlgItem(IDC_RADIO_SEMAPHORES)->EnableWindow(FALSE);
}
}
void CTheadExp2Dlg::OnBnClickedRadioMutex()
{
// TODO: 在此添加控件通知处理程序代码
//使用户斥区
g_Sel=1;
}
void CTheadExp2Dlg::OnBnClickedRadioSemaphores()
{
// TODO: 在此添加控件通知处理程序代码
//使用信号对象
g_Sel=2;
}
void CTheadExp2Dlg::OnBnClickedRadioCritical()
{
// TODO: 在此添加控件通知处理程序代码
//使用临界区
g_Sel=0;
}
void CTheadExp2Dlg::OnBnClickedExit()
{
// TODO: 在此添加控件通知处理程序代码
OnOK();
}
static void SetData(UINT dat)
{
CString str;
//使用临界区;
if(g_Sel==0)
{
//阻塞线程,测试临界区的功效:
g_Cs.Lock();
Data=dat;
str.Format("%d",Data);
::SetDlgItemText(hDlg,IDC_VALUE_SET,str);
::Sleep(1000);
g_Cs.Unlock();
}
if(g_Sel==1)//使用互斥区;
{
CSingleLock singleLock(&g_Mt);
singleLock.Lock();
Data=dat;
str.Format("%d",Data);
//阻塞线程,测试临界区的功效:
::SetDlgItemText(hDlg,IDC_VALUE_SET,str);
::Sleep(1000);
}
if(g_Sel==2)//使用信号;
{
CSingleLock singleLock(&g_Sp);
singleLock.Lock();
Data=dat;
str.Format("%d",Data);
//阻塞线程,测试临界区的功效:
::SetDlgItemText(hDlg,IDC_VALUE_SET,str);
::Sleep(1000);
}
}
static UINT GetData()
{
UINT re;
if(g_Sel==0)//使用临界区;
{
g_Cs.Lock();
re=Data;
g_Cs.Unlock();
}
if(g_Sel==1)//使用互斥区;
{
CSingleLock singleLock(&g_Mt);
singleLock.Lock();
re=Data;
}
if(g_Sel==2)//使用信号
{
CSingleLock singleLock(&g_Sp);
singleLock.Lock();
re=Data;
}
return re;
}
UINT ThreadProcWt(LPVOID param)
{
while(1)
{
for(cnt=0;cnt<10;cnt++)
{
SetData(cnt);
if(::WaitForSingleObject(g_EndTh1,0)==WAIT_OBJECT_0)
{
Data=0;
cnt=0;
OldData=0;
return 0;
}
}
}
return 0;
}
UINT ThreadProcRd(LPVOID param)
{
UINT re;
while(1)
{
re=GetData();
if(re!=OldData)
{
CString str;
str.Format("%d",re);
::SetDlgItemText(hDlg,IDC_VALUE,str);
OldData=re;
}
if(::WaitForSingleObject(g_EndTh2,0)==WAIT_OBJECT_0)
{
return 0;
}
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -