题目要求:点击抢红包后,先将第一个编辑框的值设置为1000,然后创建三个线程,让右边的编辑框值依次设置为1000(用事件完成)

// MutexExDlg.h : 头文件
// #pragma once // CMutexExDlg 对话框
class CMutexExDlg : public CDialogEx
{
// 构造
public:
CMutexExDlg(CWnd* pParent = NULL); // 标准构造函数 // 对话框数据
enum { IDD = IDD_MUTEXEX_DIALOG }; protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
static HANDLE hThread[];
static HANDLE m_Mutex;
static HANDLE m_Event;
static DWORD WINAPI ThreadProc0(LPVOID lpParameter);
static DWORD WINAPI ThreadProc1(LPVOID lpParameter);
static DWORD WINAPI ThreadProc2(LPVOID lpParameter);
static DWORD WINAPI ThreadProc3(LPVOID lpParameter); // 实现
protected:
HICON m_hIcon; // 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
afx_msg void OnBnClickedButton1();
static int m_Edit0;
static int m_Edit1;
static int m_Edit2;
static int m_Edit3;
};
// MutexExDlg.cpp : 实现文件
// #include "stdafx.h"
#include "MutexEx.h"
#include "MutexExDlg.h"
#include "afxdialogex.h" #ifdef _DEBUG
#define new DEBUG_NEW
#endif // CMutexExDlg 对话框 CMutexExDlg::CMutexExDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CMutexExDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
} void CMutexExDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, m_Edit0);
DDV_MinMaxInt(pDX, m_Edit0, , );
DDX_Text(pDX, IDC_EDIT2, m_Edit1);
DDV_MinMaxInt(pDX, m_Edit1, , );
DDX_Text(pDX, IDC_EDIT3, m_Edit2);
DDV_MinMaxInt(pDX, m_Edit2, , );
DDX_Text(pDX, IDC_EDIT4, m_Edit3);
DDV_MinMaxInt(pDX, m_Edit3, , );
} BEGIN_MESSAGE_MAP(CMutexExDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, &CMutexExDlg::OnBnClickedButton1)
END_MESSAGE_MAP() // CMutexExDlg 消息处理程序 BOOL CMutexExDlg::OnInitDialog()
{
CDialogEx::OnInitDialog(); // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此添加额外的初始化代码 return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
} // 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。 void CMutexExDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), ); // 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + ) / ;
int y = (rect.Height() - cyIcon + ) / ; // 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
} //当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CMutexExDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
} // 重写虚函数 PreTranslateMessage 屏蔽掉Esc键和Enter键
BOOL CMutexExDlg::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN)
{
int keyCode = (int)pMsg->wParam;
if (keyCode == VK_ESCAPE || keyCode == VK_RETURN)
{
return TRUE;
}
}
return CDialogEx::PreTranslateMessage(pMsg);
} HANDLE CMutexExDlg::m_Mutex = NULL;
HANDLE CMutexExDlg::m_Event = NULL;
int CMutexExDlg::m_Edit0 = ;
int CMutexExDlg::m_Edit1 = ;
int CMutexExDlg::m_Edit2 = ;
int CMutexExDlg::m_Edit3 = ;
HANDLE CMutexExDlg::hThread[] = { NULL }; // 抢红包按钮点击事件处理函数
void CMutexExDlg::OnBnClickedButton1()
{
// 获取编辑框内容到str变量
CString str;
GetDlgItem(IDC_EDIT1)->GetWindowText(str);
// CString 转 int
m_Edit0 = _ttoi(str);
m_Edit1 = ;
m_Edit2 = ;
m_Edit3 = ;
// 这里需要创建一个线程 因为 WaitForMultipleObjects 会阻塞住 另外把this指针作为参数传递给线程,用于子线程更新编辑框内容
HANDLE hThread0 = ::CreateThread(NULL, NULL, ThreadProc0, this, NULL, NULL);
CloseHandle(hThread0);
} DWORD WINAPI CMutexExDlg::ThreadProc0(LPVOID lpParameter)
{
CMutexExDlg* pDlg = (CMutexExDlg*)lpParameter;
// 创建一个事件
m_Event = ::CreateEvent(NULL,
FALSE, // FALSE 代表 WaitForSingleObject到之后,事件还是未通知状态,需要手动设置已通知状态
FALSE, // FALSE 代表 事件创建完之后,不能马上被 WaitForSingleObject 到
NULL);
// 创建三个线程抢红包
hThread[] = ::CreateThread(NULL, NULL, ThreadProc1, lpParameter, NULL, NULL);
hThread[] = ::CreateThread(NULL, NULL, ThreadProc2, lpParameter, NULL, NULL);
hThread[] = ::CreateThread(NULL, NULL, ThreadProc3, lpParameter, NULL, NULL);
// 设置编辑框内容
::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT1), L"");
// 将对象设置为已通知状态
::SetEvent(m_Event);
// 使用WaitForMultipleObjects监听所有线程,当线程全部结束后,调用CloseHandle关闭句柄.
WaitForMultipleObjects(, hThread, TRUE, -);
::CloseHandle(hThread[]);
::CloseHandle(hThread[]);
::CloseHandle(hThread[]);
::CloseHandle(m_Mutex);
return ;
} // 线程回调函数1
DWORD WINAPI CMutexExDlg::ThreadProc1(LPVOID lpParameter)
{
CMutexExDlg* pDlg = (CMutexExDlg*)lpParameter;
while (true)
{
WaitForSingleObject(m_Event, -);
::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT2), L"");
Sleep();
// 将对象设置为已通知状态
::SetEvent(m_Event);
}
return ;
} // 线程回调函数2
DWORD WINAPI CMutexExDlg::ThreadProc2(LPVOID lpParameter)
{
CMutexExDlg* pDlg = (CMutexExDlg*)lpParameter;
while (true)
{
WaitForSingleObject(m_Event, -);
::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT3), L"");
Sleep();
// 将对象设置为已通知状态
::SetEvent(m_Event);
}
return ;
} // 线程回调函数3
DWORD WINAPI CMutexExDlg::ThreadProc3(LPVOID lpParameter)
{
CMutexExDlg* pDlg = (CMutexExDlg*)lpParameter;
while (true)
{
WaitForSingleObject(m_Event, -);
::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT4), L"");
Sleep();
// 将对象设置为已通知状态
::SetEvent(m_Event);
}
return ;
}

C++线程同步之事件的更多相关文章

  1. C++线程同步之事件(生产者与消费者问题)

    #include <windows.h> #include <stdio.h> HANDLE g_hSet = NULL; HANDLE g_hClear = NULL; HA ...

  2. Python并行编程(七):线程同步之事件

    1.基本概念 事件是线程之间用于通讯的对象.有的线程等待信号,有的线程发出信号.基本上事件对象都会维护一个内部变量,可以通过set方法设置为true,也可以通过clear方法设置为false.wait ...

  3. MFC线程(三):线程同步事件(event)与互斥(mutex)

    前面讲了临界区可以用来达到线程同步.而事件(event)与互斥(mutex)也同样可以做到. Win32 API中的线程事件 HANDLE hEvent = NULL; void MainTestFu ...

  4. C++线程同步的四种方式(Windows)

    为什么要进行线程同步? 在程序中使用多线程时,一般很少有多个线程能在其生命期内进行完全独立的操作.更多的情况是一些线程进行某些处理操作,而其他的线程必须对其处理结果进行了解.正常情况下对这种处理结果的 ...

  5. Delphi多线程编程--线程同步的方法(事件、互斥、信号、计时器)简介

    更详细的可以参考:http://www.cnblogs.com/xumenger/p/4450659.html 或者参考之后的博客 四个系统内核对象(事件.互斥.信号.计时器)都是线程同步的手段,从这 ...

  6. [C++] socket - 5 [API事件对象实现线程同步]

    /*API事件对象实现线程同步*/ #include<windows.h> #include<stdio.h> DWORD WINAPI myfun1(LPVOID lpPar ...

  7. 经典线程同步 事件Event

    阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇 一个经典的多线程同步问题> <秒杀多线程第五篇 经典线程同步关键段CS> 上一篇中使用关键段来解决经典的多线程同步互斥问题 ...

  8. C#多线程:深入了解线程同步lock,Monitor,Mutex,同步事件和等待句柄(中)

    本篇继续介绍WaitHandler类及其子类 Mutex,ManualResetEvent,AutoResetEvent的用法..NET中线程同步的方式多的让人看了眼花缭乱,究竟该怎么去理解呢?其实, ...

  9. 多线程面试题系列(6):经典线程同步 事件Event

    上一篇中使用关键段来解决经典的多线程同步互斥问题,由于关键段的"线程所有权"特性所以关键段只能用于线程的互斥而不能用于同步.本篇介绍用事件Event来尝试解决这个线程同步问题.首先 ...

随机推荐

  1. Android相关属性的介绍:android:exported = true

    在Activity中该属性用来标示:当前Activity是否可以被另一个Application的组件启动:true允许被启动:false不允许被启动. android:exported 是Androi ...

  2. CEF拦截js层alert弹窗 OnJSDialog 《转》

    一 引言 CEF3嵌入后,用JS 弹出Alert框,按钮错位,确定按钮勉强能看到.很难看.为了改善体验,决定重写提示框. 环境:VS2008  VC  MFC.   二 原理 参看类 CefJSDia ...

  3. 【深入学习linux】VMware新建虚拟机教程

    新建虚拟机 1. 点击创建新的虚拟机 2.进入新建向导,选择典型安装,点击下一步 3.为什么不选择第二个选项是因为系统会默认帮助我们安装一个简单配置,这里我们需要学习配置安装所以选择第三项,然后点击下 ...

  4. SQL优化-如何分析性能瓶颈

    MySQL优化一览图 笔者将优化分为了两大类:软优化和硬优化.软优化一般是操作数据库即可:而硬优化则是操作服务器硬件及参数设置. 1.软优化 1)查询语句优化 首先我们可以用EXPLAIN或DESCR ...

  5. JAVA微信开发-如何保存包含特殊字符的微信昵称

    我们在做微信开发的时候,有一个很重要的就是通过openid获取用户的详细信息,包含昵称,头像,省,市,区的信息,但是现在移动时代,很多人追求个性,在名字当中大量使用火星文或者表情符.(本人实际测试过一 ...

  6. Mysql中的Date转换

    一.背景 Mysql中有张表,表的一列为Date类型. 1. 插入日期xxx.setCreateTime(new Date())mybatis.insert(xxx) 2. 读取日期用Mybaitis ...

  7. LC 968. Binary Tree Cameras

    Given a binary tree, we install cameras on the nodes of the tree. Each camera at a node can monitor  ...

  8. 关于Objective-C新增的__kindof关键字

    Objective-C随着Xcode 7的升级带来了许多新特性,当然此次更新最最大的就是引入了Objective-C的轻量级泛型,确切地说是Objective-C类的轻量级泛型.除此之外,还有一个小特 ...

  9. 利用Flex&b 开发一门语言

    https://blog.csdn.net/CrazyHeroZK/article/details/87359818

  10. [LeetCode] 87. Scramble String 爬行字符串

    Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrin ...