栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++跨平台开发——解决共享内存实现进程互发消息的BUG

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++跨平台开发——解决共享内存实现进程互发消息的BUG

        在之前写的利用共享内存实现进程间发送消息中,如果细心的同学可能发现了一系列的问题,基于大佬的讲解,我对出现的BUG做了一些分析和总结

C++跨平台开发——共享内存实现进程间发送消息

一、BUG——共享内存没有写成功就去读

        首先请思考读端什么时候读数据?即什么时候能让你知道共享内存中有了数据?

        因为读的时候直接就memcpy了,本来在调用memcpy之前应该有一个逻辑在证明共享内存中有数据,这样的逻辑才是正常的,如果共享内存中还没有数据的话memcpy出来就是内存中的乱码。但是你又需要读出来才知道共享内存中有没有数据,所以就产生了BUG——都没有写成功就去读

        因为之前的读都用的read(阻塞函数),如果你没有操作完(没写完数据)read是不会有问题的(保证读到数据再继续)。但是因为memcpy没有阻塞,就可能产生还没有写完数据到共享内存就去读了(当然也不能在memcpy后去判断,因为memcpy已经读了数据)

        而像之前学习的信号有对应的信号处理函数(信号发到位了才去处理);管道针对的是IO流,可以使用死循环加阻塞函数read也不会有问题;消息队列也是利用死循环加msgrcv阻塞函数。这些都不需要我们做判断,但因为memcpy没有阻塞,导致立刻执行出现BUG

二、错误解决方法 1、利用sizeof或者strlen判断结构体中的长度

就算memcpy后没有数据,sizeof也永远大于0。

strlen是判断是否有字符,但是读出来的数据可能是烫烫烫或者n这样的字符,所以用strlen也会出现问题

2、仅使用两块共享内存 

也是跟上面一样的问题,一方写完,对方仍然不知道什么时候开始读

 3、使用sleep或者wait

①极端:写一个“你”,等几分钟再写“好”,根本不知道sleep多久

②如果A程序运行起来,B程序还没运行,根本不知道B程序的pid是多少

4、使用信号

 发送信号,A进程也是不知道B进程的pid,没法实现

三、解决方法——使用消息队列 好处

1)消息可以一行一行的追加,如果消息没有被读取走,消息将会被永远保留,如果你想读取,将会按照顺序逐行读取(第几个消息发出去,你绝对是你几个收)

2)没有任何时间间隔,因为msgrcv是阻塞函数,有消息才收,没消息就阻塞(不像信号,必须知道对方的pid才能通知对方,还可能产生信号冲突问题)

实现框架如下图所示(消息队列结合共享内存)

①写完共享内存

②创建消息队列, A进程写完给消息队列发消息

③B进程阻塞,等待接收消息

④接收到消息就进行memcpy

提供完解决方法后,就可以真正实现互发消息啦

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/779632.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号