C++ PostMessage能否生成变量';GetMessage之后UI线程中可见的工作线程中的更改?

C++ PostMessage能否生成变量';GetMessage之后UI线程中可见的工作线程中的更改?,c++,windows,multithreading,C++,Windows,Multithreading,我的问题是,如果我在另一个线程中写入一个变量,然后将PostMessage写入一个Wnd,UI线程中的GetMessage是否会与它同步,并且我可以安全地读取该变量 背景是:我想使用PostMessage从后台线程更新UI,并且担心数据竞争。我需要其他同步工具吗 谢谢 编辑: 标题很混乱,所以请更改它 要详细说明这一情况: 假设我想更新一个std::string,它是一个全局变量。由于我在PostMessage之前更新了字符串,我可以安全地读取处理该消息的窗口进程中的字符串 我熟悉C++11多线

我的问题是,如果我在另一个线程中写入一个变量,然后将
PostMessage
写入一个Wnd,UI线程中的
GetMessage
是否会与它同步,并且我可以安全地读取该变量

背景是:我想使用
PostMessage
从后台线程更新UI,并且担心数据竞争。我需要其他同步工具吗

谢谢

编辑: 标题很混乱,所以请更改它

要详细说明这一情况: 假设我想更新一个
std::string
,它是一个全局变量。由于我在
PostMessage
之前更新了
字符串
,我可以安全地读取处理该消息的窗口进程中的
字符串

我熟悉C++11多线程术语,如
发生在
之前、
序列在
之前、
同步和
发布获取
概念,因此我的问题可以用另一种方式回答:

写入
字符串
是否发生在读取之前


PS:假设这是一次性的,工作线程不会一次又一次地更新
字符串。

Windows消息队列是线程安全的生产者-消费者队列。MSG结构(仅此而已)被复制到队列中,因此消息发布后,您可以毫无问题地重新加载自己的消息数据和PostMessage

当开发人员将消息指针/引用作为wParam、lParam进行后期处理时,生命周期会出现问题。如果指针指向本地堆栈对象,则在接收GetMessage/wndProc中处理指向它的指针之前,它可能会被删除。类似地,如果指向用new实例化的对象的指针在GetMessage线程中处理之前在发布线程中被显式删除


如果您提供更多有关您正在发送邮件的数据的详细信息,我们将能够为您提供建议

Windows消息队列是线程安全的生产者-消费者队列。MSG结构(仅此而已)被复制到队列中,因此消息发布后,您可以毫无问题地重新加载自己的消息数据和PostMessage

当开发人员将消息指针/引用作为wParam、lParam进行后期处理时,生命周期会出现问题。如果指针指向本地堆栈对象,则在接收GetMessage/wndProc中处理指向它的指针之前,它可能会被删除。类似地,如果指向用new实例化的对象的指针在GetMessage线程中处理之前在发布线程中被显式删除


如果您提供更多有关您正在发送邮件的数据的详细信息,我们将能够为您提供建议

不,你对此没有控制权
PostMessage
确实是异步的,在处理消息时,这两个线程中已经发生了许多事情(包括处理先前发布的消息和发送的消息(通过SendMessage))

根据您想做什么,您可以:

  • 异步传输数据的副本(
    malloc
    /
    new
    )和
    PostMessage
    (指针位于
    wParam
    lParam
  • 使用
    SendMessage
  • 使用
    发送消息
    同步传输数据副本,以及

  • 不可以。您对此没有任何控制权。
    PostMessage
    确实是异步的,在处理消息时,两个线程中发生了许多事情(包括处理先前发布的消息和发送的消息(通过SendMessage))

    根据您想做什么,您可以:

  • 异步传输数据的副本(
    malloc
    /
    new
    )和
    PostMessage
    (指针位于
    wParam
    lParam
  • 使用
    SendMessage
  • 使用
    发送消息
    同步传输数据副本,以及

  • 它可以保证UI线程将使用数据并安全地更新windows。到此为止,您仍然有另一个线程正在从写入数据的线程读取数据,因此需要正常联锁以确保UI线程不会读取更改的数据

    这是一个很常见的问题,您无法确切地知道UI线程何时检索消息。如果UI线程陷入困境,可能需要很长时间。因此,除非您明确握手,否则您无法知道工作线程何时可以继续更新数据或何时可以发布另一条消息。创建数据解决了这个问题。或者你需要一个自动重置事件来握手,小心它会导致死锁

    您必须处理的另一种可能的失败模式是PostMessage()可能会失败。当UI线程因任何原因陷入困境时,都会发生这种情况。每当消息队列大小超过配额(默认情况下为10000条消息)时,您将得到一个错误的返回。对此您无能为力,只能休眠一段时间然后重试


    当您遇到消防水管问题时,您也会调用此故障模式,工作线程生成数据的速度快于UI线程所能跟上的速度。消防水管非常棘手,因为在启动或调试程序时,很少使用有限的数据集。诊断为WM_PAINT notif的丢失除此之外,您的UI似乎冻结了,即使它仍然处于活动状态,并且正在积极处理已发布邮件的积压。您可以通过保持在人眼可以感知到的UI更新速度以北的方式来避免这种情况。这很好而且很慢,当您每秒更新超过25次时,所有这些都会变成无法读取的模糊信息。

    您可以保证UI线程将使用数据并可以安全地更新windows