最近在接入英飞拓dvr的视频,附带sdk为32位,而运行环境为64位,只好用内存映射在两个独立进程之间传递码流,用消息同步内存映射。
考虑到不同通道要new不同的对象,new不同的对象就要分配不通的内存映射id与消息id,为了两个进程的id同步,就采用通道号加10与加11分别作为消息id与内存映射id。
一个通道反复取流、停止操作均正常,(测试20次,20次之内均正常)。但是同时开两个通道,关闭任何一个通道就出问题,具体如下(具体操作顺序即描述顺序):
一、打开1通道,打开2通道,关闭1通道,程序崩溃,提示通道2的消息发送出错;
二、打开1通道,打开2通道,关闭2通道,程序未崩溃,1通道同时停止播放,再次播放任意通道无效;
三、打开2通道,打开1通道,关闭1通道,程序崩溃,提示通道2的消息发送出错;
四、打开2通道,打开1通道,关闭2通道,程序未崩溃,1通道同时停止播放,再次播放任意通道无效。
一开始以为是类的原因,以为是map的原因,以为是SDK调用(关闭部分)不彻底,以为是两个进程的启动、关闭顺序不协调,反复调试n次,添加打印n二次方次,始终如上出错!
分析:
因为每次关闭某个通道都要清除对应的内存映射id与消息id,按照上述,通道1的消息id为11,内存映射id为12,而通道2的消息id为12,内存映射id为13,所以每次关闭通道1时,销掉11和12这两个id,即同时也销掉了通道2的消息id,剩下的就不用再详述了。。。
解决方案:
解决方法就是一个加10,另一个加20或其他更大的数,注意两个进程均要做同样更改。
附加,之前内存映射遇到另一个奇葩,在这里一起描述下:
总之一句话,取内存映射操作的内存映射分配大小决定了写内存映射操作的内存映射分配大小。
之前取方的大小设为2000,然后写方的大小就改不了,将一帧拆着发,收到后又打包,导致数据完整性很脆弱,直到将取方的大小设成一个大数,不用拆帧传输,确保数据完整。