博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++线程同步之事件
阅读量:4507 次
发布时间:2019-06-08

本文共 5915 字,大约阅读时间需要 19 分钟。

题目要求:点击抢红包后,先将第一个编辑框的值设置为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[3];    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, 0, 1000);    DDX_Text(pDX, IDC_EDIT2, m_Edit1);    DDV_MinMaxInt(pDX, m_Edit1, 0, 1000);    DDX_Text(pDX, IDC_EDIT3, m_Edit2);    DDV_MinMaxInt(pDX, m_Edit2, 0, 1000);    DDX_Text(pDX, IDC_EDIT4, m_Edit3);    DDV_MinMaxInt(pDX, m_Edit3, 0, 1000);}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
(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 { CDialogEx::OnPaint(); }}//当用户拖动最小化窗口时系统调用此函数取得光标//显示。HCURSOR CMutexExDlg::OnQueryDragIcon(){ return static_cast
(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 = 0;int CMutexExDlg::m_Edit1 = 0;int CMutexExDlg::m_Edit2 = 0;int CMutexExDlg::m_Edit3 = 0;HANDLE CMutexExDlg::hThread[3] = { NULL };// 抢红包按钮点击事件处理函数void CMutexExDlg::OnBnClickedButton1(){ // 获取编辑框内容到str变量 CString str; GetDlgItem(IDC_EDIT1)->GetWindowText(str); // CString 转 int m_Edit0 = _ttoi(str); m_Edit1 = 0; m_Edit2 = 0; m_Edit3 = 0; // 这里需要创建一个线程 因为 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[0] = ::CreateThread(NULL, NULL, ThreadProc1, lpParameter, NULL, NULL); hThread[1] = ::CreateThread(NULL, NULL, ThreadProc2, lpParameter, NULL, NULL); hThread[2] = ::CreateThread(NULL, NULL, ThreadProc3, lpParameter, NULL, NULL); // 设置编辑框内容 ::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT1), L"1000"); // 将对象设置为已通知状态 ::SetEvent(m_Event); // 使用WaitForMultipleObjects监听所有线程,当线程全部结束后,调用CloseHandle关闭句柄. WaitForMultipleObjects(3, hThread, TRUE, -1); ::CloseHandle(hThread[0]); ::CloseHandle(hThread[1]); ::CloseHandle(hThread[2]); ::CloseHandle(m_Mutex); return 0;}// 线程回调函数1DWORD WINAPI CMutexExDlg::ThreadProc1(LPVOID lpParameter){ CMutexExDlg* pDlg = (CMutexExDlg*)lpParameter; while (true) { WaitForSingleObject(m_Event, -1); ::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT2), L"1000"); Sleep(2000); // 将对象设置为已通知状态 ::SetEvent(m_Event); } return 0;}// 线程回调函数2DWORD WINAPI CMutexExDlg::ThreadProc2(LPVOID lpParameter){ CMutexExDlg* pDlg = (CMutexExDlg*)lpParameter; while (true) { WaitForSingleObject(m_Event, -1); ::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT3), L"1000"); Sleep(2000); // 将对象设置为已通知状态 ::SetEvent(m_Event); } return 0;}// 线程回调函数3DWORD WINAPI CMutexExDlg::ThreadProc3(LPVOID lpParameter){ CMutexExDlg* pDlg = (CMutexExDlg*)lpParameter; while (true) { WaitForSingleObject(m_Event, -1); ::SetWindowText(::GetDlgItem(pDlg->m_hWnd, IDC_EDIT4), L"1000"); Sleep(2000); // 将对象设置为已通知状态 ::SetEvent(m_Event); } return 0;}

 

转载于:https://www.cnblogs.com/duxie/p/11123573.html

你可能感兴趣的文章
工作多年后积累的设计灵活,稳定,优秀WinForms应用程序的最佳实践 WinForms best practice...
查看>>
iOS开发——高级篇——iOS键盘的相关设置(UITextfield)
查看>>
JVMGC机制
查看>>
IAR for AVR 报array is too large错误 【已解决】
查看>>
老子《道德经》第六十二章
查看>>
Junit问题01 利用 @Autowired 注入失效问题
查看>>
20180711
查看>>
Js常见的创建对象
查看>>
IOS拖动
查看>>
httpclient的使用
查看>>
Kafka集群副本分配算法解析
查看>>
vue单页面条件下添加类似浏览器的标签页切换功能
查看>>
lambda表达式10个示例——学习笔记
查看>>
python 文件操作
查看>>
Java多线程之后台线程
查看>>
浏览器兼容性
查看>>
非均衡分类问题的思考与问题与解决思路
查看>>
头文件与extern
查看>>
python开发技术详解(三) 进阶的语法
查看>>
LeetCode Missing Number
查看>>