关于线程消息队列的参数生命期

aled6825 2016-05-04 07:15:32
查询网络,好像没有对这个问题有专业的解答。这里抛个砖,看有无对这块儿研究精深的帮大家解个惑。

异步线程一般使用PostThreadMessage向目标线程传递消息,特别适用于日志中心这种收集器类线程。这个函数的原型是:
BOOLPostThreadMessage( DWORD idThread, UINT Msg,WPARAM wParam,LPARAM IParam);

这个函数是异步的,如果收集器线程繁忙,它会把消息存储在消息队列中,而自身直接返回。

现在问题在这里,该函数携带的两个参数wParam和IParam,如果定义为非指针型,如果消息队列等待时间足够长,它可能会因为调用者函数生命期完成而自身销毁,而指针型new出来的参数,却无法在GetMessage后delete销毁,报CRT错误。

何解?哪位精研过这一块儿,还望帮忙解答,谢谢!
...全文
163 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Saleayas 2016-05-06
  • 打赏
  • 举报
回复
消息队列一般都是在一个进程中,而且消息的发送和处理是有一个工程完成的。可以直接使用 new delete。 如果,你不是有同一个工程来完成,那么就不能使用 new/delete . 看看 COM 组件的 Release 就是完成这个的。
aled6825 2016-05-05
  • 打赏
  • 举报
回复
问题已解决。 前一个说法是对的,但我的问题根子还在 对堆栈的理解浅薄上。由于线程分布在不同的DLL、EXE上,其并不隶属于同一个CRT,malloc或者new出来的东西,跨越堆是无法成功释放的。 有效解法是使用全局堆内存分配GlobalAlloc和GlobalFree,当然还有其他解法,各位自行研究。 参考文章: DLL和exe里的malloc和free不能混用 结贴,敬谢!
dustpg 2016-05-05
  • 打赏
  • 举报
回复
删除的话,参考COM接口,调用一个虚函数释放。
aled6825 2016-05-05
  • 打赏
  • 举报
回复

在内存理解上,最著名的例子就是线程启动时的参数传递。
  函数启动一个线程,很多时候需要向线程传参数,但是线程是异步启动的,即很可能启动函数已经退出了,而线程函数都还没有正式开始运行,因此,绝不能用启动函数的内部变量给线程传参。道理很简单,函数的内部变量在浮动栈,但函数退出时,浮动栈自动拆除,内存空间已经被释放了。当线程启动时,按照给的参数指针去查询变量,实际上是在读一块无效的内存区域,程序会因此而崩溃。

  那怎么办呢?我们应该直接用malloc函数给需要传递的参数分配一块内存区域,将指针传入线程,线程收到后使用,最后线程退出时,free释放。
这段话也许是症结所在。
aled6825 2016-05-05
  • 打赏
  • 举报
回复
引用 4 楼 Saleayas 的回复:
好奇怪哦~ 如果你的某个参数是一个内存指针,那么Post 成功之后, 应该有消息处理函数来销毁,Post 成功之后,消息处理一定会处理的。 如果 Post 不成功,那么应该自己销毁。
首先确认的是Post是成功的,我的TRACE结果是酱紫:AppMsg - PostThreadMessage=1 按理,生产者new,消费者delete是标准处理模式,可这里消费者却无法delete该内存区域。 BTW,消费者是固定的,生产者不固定,可能由任意的线程产生,是不是线程保护?
Saleayas 2016-05-05
  • 打赏
  • 举报
回复
好奇怪哦~ 如果你的某个参数是一个内存指针,那么Post 成功之后, 应该有消息处理函数来销毁,Post 成功之后,消息处理一定会处理的。 如果 Post 不成功,那么应该自己销毁。
列子汤问 2016-05-04
  • 打赏
  • 举报
回复
我印象中 PostThreadMessage的消息如果不被处理的话,不会无限期的放在消息队列的。
aled6825 2016-05-04
  • 打赏
  • 举报
回复
生产者消费者模型是可以解决该问题的,但我想了解的事PostThreadMessage以后都发生了些什么.

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧