zoukankan      html  css  js  c++  java
  • C++第五十二篇 -- 多线程之消息传递

    主线程向子线程发送消息

    参考链接:https://www.cnblogs.com/ranjiewen/p/5729539.html

    1. 创建线程语句

        HANDLE hThread;
        DWORD dwThreadId[3];
        for (int i = 0; i < 3; i++) {
            hThread = CreateThread(NULL, 0, FunProc, &i, 0, &dwThreadId[i]);
            CloseHandle(hThread);
        }

    2. 向子线程发送消息语句。

      a. 在.cpp最上面定义#define MY_MSG WM_USER+100

            for (int j = 0; j < 3; j++) {
                if (!PostThreadMessage(dwThreadId[j], MY_MSG, 0, 0)) {
                    printf("post message failed,errno:%d
    ", ::GetLastError());
                }
            }

    3.1 线程函数接收消息不阻塞

    DWORD WINAPI FunProc(LPVOID lpParameter)
    {
        MSG msg;
        int i = 0;
        while (TRUE)
        {
            if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
            {
                if (msg.message == MY_MSG)
                    break;
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
            i++;
            printf("i = %d
    ", i);
            Sleep(1000);        
        }
        return 0;
    }

    此时接收消息用的是PeekMessage函数,此函数不会阻塞线程。如果此时有消息传来,那么返回的是TRUE,如果没有消息传来,返回的就是FALSE。这个函数的含义是每隔一秒输出一次i,直到有消息传递给线程,那么线程结束。

    3.2 线程接收消息阻塞

    DWORD WINAPI FunProc(LPVOID lpParameter)
    {
        MSG msg;
        int i = 0;
        BOOL stop_thread = FALSE;
        while (!stop_thread)
        {
            if (GetMessage(&msg, 0, 0, 0)) {
                switch (msg.message)
                {
                case MY_MSG:
                    stop_thread = TRUE;
                    break;
                }
            }
            i++;
            printf("i = %d
    ", i);
            Sleep(1000);        
        }
        return 0;
    }

    此时接收消息用的是GetMessage函数,此函数会阻塞在if语句那儿,直到有消息传来,才会继续下去,所以这个线程只会输出一次i就结束了。

    SubWin1.cpp

    // SubWin1.cpp : implementation file
    //
    
    #include "stdafx.h"
    #include "Project2.h"
    #include "SubWin1.h"
    #include "afxdialogex.h"
    #include "resource.h"
    
    
    // SubWin1 dialog
    #define MY_MSG WM_USER+100
    //const int MAX_INFO_SIZE = 20;
    
    IMPLEMENT_DYNAMIC(SubWin1, CDialog)
    
    SubWin1::SubWin1(CWnd* pParent /*=nullptr*/)
        : CDialog(IDD_SubWin1, pParent)
    {
    
    }
    
    SubWin1::~SubWin1()
    {
    }
    
    void SubWin1::DoDataExchange(CDataExchange* pDX)
    {
        CDialog::DoDataExchange(pDX);
    }
    
    
    BEGIN_MESSAGE_MAP(SubWin1, CDialog)
        ON_WM_TIMER()
        ON_WM_CLOSE()
    END_MESSAGE_MAP()
    
    
    // SubWin1 message handlers
    
    DWORD WINAPI FunProc(LPVOID lpParameter)
    {
        MSG msg;
        //DWORD id_thread = GetCurrentThreadId();
        //printf("id_thread = %d
    ", id_thread);
        int i = 0;
        BOOL stop_thread = FALSE;
        while (!stop_thread)
        {
            //if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
            //{
            //    if (msg.message == MY_MSG)
            //        break;
            //    TranslateMessage(&msg);
            //    DispatchMessage(&msg);
            //}
            if (GetMessage(&msg, 0, 0, 0)) {
                switch (msg.message)
                {
                case MY_MSG:
                    stop_thread = TRUE;
                    break;
                }
            }
            i++;
            printf("i = %d
    ", i);
            Sleep(1000);        
        }
        return 0;
    }
    
    
    BOOL SubWin1::OnInitDialog()
    {
        CDialog::OnInitDialog();
    
        // TODO:  Add extra initialization here
    
        HANDLE hThread;
        for (int i = 0; i < 3; i++) {
            hThread = CreateThread(NULL, 0, FunProc, &i, 0, &dwThreadId[i]);
            CloseHandle(hThread);
        }
        
    
        SetTimer(0, 1000, NULL); //设置一秒刷新一次
    
        return TRUE;  // return TRUE unless you set the focus to a control
                      // EXCEPTION: OCX Property Pages should return FALSE
    }
    
    
    void SubWin1::OnTimer(UINT_PTR nIDEvent)
    {
        // TODO: Add your message handler code here and/or call default
        escape_time++;
        if (escape_time > 10) {
            for (int j = 0; j < 3; j++) {
                if (!PostThreadMessage(dwThreadId[j], MY_MSG, 0, 0)) {
                    printf("post message failed,errno:%d
    ", ::GetLastError());
                }
            }
            EndDialog(0x00);
        }
    
        CDialog::OnTimer(nIDEvent);
    }
    
    
    void SubWin1::OnClose()
    {
        // TODO: Add your message handler code here and/or call default
        for (int j = 0; j < 3; j++) {
            if (!PostThreadMessage(dwThreadId[j], MY_MSG, 0, 0)) {
                printf("post message failed,errno:%d
    ", ::GetLastError());
            }
        }
    
        CDialog::OnClose();
    }
    View Code

    这个程序起源于创建一个Dll带MFC库,前面有讲过这一章节内容。

  • 相关阅读:
    Cookie中用户登录信息的提示
    利用CentOS系统IPtables防火墙添加网站IP白名单
    php5.3升级到5.5
    nginx+apache 404错误页面
    启用nginx status状态详解
    nginx前端负载,后端apache获取真实IP设置
    CentOS查看系统信息-CentOS查看命令
    nginx负载 发向代理配置文件参考
    Linux添加用户(user)到用户组(group)
    Centos6.5快速配置可用网卡
  • 原文地址:https://www.cnblogs.com/smart-zihan/p/14902771.html
Copyright © 2011-2022 走看看