线程间通讯:PostThreadMessage

目录

1、PostThreadMessage的函数原型

2、PostThreadMessage一个简单的示例

3、实际应用中,会用 BEGIN_MESSAGE_MAP 宏定义消息映射表(MFC)


PostThreadMessage是一个Windows API函数,用于向指定线程的消息队列中发送一个消息。

1、PostThreadMessage的函数原型

BOOL PostThreadMessage(
  DWORD  idThread,
  UINT   Msg,
  WPARAM wParam,
  LPARAM lParam
);

参数说明:

  • idThread:要发送消息的目标线程的ID。
  • Msg:要发送的消息类型。
  • wParam:消息的附加参数。
  • lParam:消息的附加参数。

PostThreadMessage函数将消息发送到指定线程的消息队列中,然后立即返回。线程可以通过调用GetMessage或PeekMessage函数来获取并处理该消息。该函数通常用于线程间的通信,可以用来传递自定义消息或系统消息,从而实现线程之间的协作和信息交换。

2、PostThreadMessage一个简单的示例

演示如何使用PostThreadMessage向另一个线程发送消息:

#include <windows.h>
#include <iostream>

DWORD WINAPI ThreadProc(LPVOID lpParam)
{
    MSG msg;
    HWND hWnd = (HWND)lpParam;

    // 等待消息循环
    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (msg.message == WM_USER)
        {
            std::cout << "Received custom message." << std::endl;
        }
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

int main()
{
    // 创建一个新线程
    DWORD threadId;
    HANDLE hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, &threadId);
    if (hThread == NULL)
    {
        std::cout << "Failed to create thread." << std::endl;
        return 1;
    }

    // 等待一段时间
    Sleep(1000);

    // 向线程发送消息
    if (!PostThreadMessage(threadId, WM_USER, 0, 0))
    {
        std::cout << "Failed to post thread message." << std::endl;
        return 1;
    }

    // 等待线程结束
    WaitForSingleObject(hThread, INFINITE);

    // 关闭线程句柄
    CloseHandle(hThread);

    return 0;
}

在上述示例中,我们创建了一个新的线程,并通过CreateThread函数启动。然后,我们使用PostThreadMessage函数向该线程发送一个自定义消息(WM_USER)。在线程的消息循环中,我们通过GetMessage函数获取消息并进行处理。在本例中,我们判断接收到的消息是否为自定义消息WM_USER,并进行相应的处理。然后,我们等待线程结束并关闭线程句柄。

请注意,上述示例中的线程函数ThreadProc是一个简单的消息循环,用于处理线程收到的消息。在实际应用中,您可能需要根据需要自定义消息处理过程。

3、实际应用中,会用 BEGIN_MESSAGE_MAP 宏定义消息映射表(MFC)

将自定义消息和处理函数一一对应起来

(1)先了解下BEGIN_MESSAGE_MAP 

BEGIN_MESSAGE_MAP 是一个宏定义,用于在 MFC(Microsoft Foundation Classes)中定义消息映射表。MFC 是微软提供的一套用于开发 Windows 应用程序的类库,它封装了许多常用的 Windows API 函数和功能,简化了 Windows 应用程序的开发过程。

在 MFC 中,消息映射是一种机制,用于将窗口消息(如鼠标点击、键盘输入等)与对应的处理函数关联起来。通过使用 BEGIN_MESSAGE_MAP 宏定义,可以在类的声明中定义一个消息映射表,将消息与处理函数进行关联。

消息映射表由一系列的消息映射宏组成,每个消息映射宏都指定了一个消息 ID 和对应的处理函数。当窗口接收到相应的消息时,MFC 会自动调用对应的处理函数进行处理。

(2)以下是一个示例代码片段,展示了如何使用 BEGIN_MESSAGE_MAP 宏定义消息映射表:

"afx_msg" 是一个宏定义,用于在 MFC 框架中声明一个成员函数。它是用于处理消息的函数的前缀,用于将成员函数与消息映射起来。在 MFC 中,消息是通过 Windows 消息机制传递的,而 "afx_msg" 宏则用于指定成员函数是用于处理特定消息的。

class CThreadDevice: public CThreadBase
{
public:
  // ...

protected:
	//执行下发数据功能操作
	afx_msg void OnMsgIssueData(WPARAM wParam,LPARAM lParam);
	//执行启动获取数据的操作
	afx_msg void OnMsgStartGetData(WPARAM wParam,LPARAM lParam);
	//执行停止获取数据的操作
	afx_msg void OnMsgStopGetData(WPARAM wParam,LPARAM lParam);
	//接收到硬件推送的消息,进行数据获取
	afx_msg void OnMsgGetData(WPARAM wParam,LPARAM lParam);

	DECLARE_MESSAGE_MAP()
};


BEGIN_MESSAGE_MAP(CThreadDevice, CThreadBase)
	ON_THREAD_MESSAGE(WM_THREAD_NFC_ISSUE_DATA, OnMsgIssueData)
	ON_THREAD_MESSAGE(WM_THREAD_DEVICE_START_GET_DATA, OnMsgStartGetData)
	ON_THREAD_MESSAGE(WM_THREAD_DEVICE_STOP_GET_DATA, OnMsgStopGetData)
	ON_THREAD_MESSAGE(WM_THREAD_DEVICE_NOTIFY, OnMsgGetData)

END_MESSAGE_MAP()

通过 DECLARE_MESSAGE_MAP 宏将消息映射表声明为类的一部分,并使用 BEGIN_MESSAGE_MAP 宏开始定义消息映射表,然后使用 ON_THREAD_MESSAGE  宏将消息 ID 和对应的处理函数进行关联,最后使用 END_MESSAGE_MAP 宏结束消息映射表的定义。

ON_THREAD_MESSAGE是一个事件类型,表示当在一个线程中收到消息时触发的事件。

(3)在需要执行该函数功能的时候,发出请求

// 声明一个变量
CThreadDevice*		m_pThreadDevice;

// 发出请求
m_pThreadDevice->PostThreadMessage(WM_THREAD_NFC_ISSUE_DATA, (WPARAM)wParam, (LPARAM)0);

该线程收到这个自定义消息时候,就会执行映射表里对应的函数OnMsgIssueData。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]:在MFC环境下实现多线程串口通信,需要涉及线程创建及控制、串口同步异步操作、内存非法访问(或者说是线程同步)、线程通信、Windows消息响应过程等。\[1\]在多线程访问冲突方面,可能会遇到一个问题,即主线程和IO线程同时使用同一个串口通信缓冲区,导致非法访问。解决方法可以是将所有的串口IO通信交给子线程来处理,主线程通过发送消息给子线程来实现通信,可以使用API函数PostThreadMessage来发送消息给子线程,其中第一个参数是子线程的ID。\[2\]在MFC中,可以使用AfxBeginThread函数来创建新的线程,该函数返回线程的指针。在创建线程时,需要指定线程函数地址、线程参数、线程优先级等参数。\[3\] 问题: 如何在MFC中实现串口通信的多线程? 回答: 在MFC中实现串口通信的多线程,可以按照以下步骤进行操作。首先,需要创建一个新的线程来处理串口通信。可以使用AfxBeginThread函数来创建线程,该函数需要指定线程函数地址、线程参数、线程优先级等参数。在线程函数中,可以调用相应的串口通信函数来进行数据的发送和接收。为了避免多线程访问冲突,可以将所有的串口IO通信交给子线程来处理,主线程通过发送消息给子线程来实现通信。可以使用API函数PostThreadMessage来发送消息给子线程,其中第一个参数是子线程的ID。通过这种方式,可以实现主线程和子线程的数据交互和同步操作。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *2* [多线程串口通信 MFC CSerialPort](https://blog.csdn.net/denggou1893/article/details/101238521)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [c++学习 | MFC —— 串口通信(二)创建线程](https://blog.csdn.net/florence_jz/article/details/125913281)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值