进程通信(持续更新)

6 篇文章 0 订阅
4 篇文章 0 订阅


前言

业务层处理好媒体业务时,需要和编解码模块进行通信,即业务进程和编解码进程间的指令数据通信,mmap映射是一种进程通信方式。也是遇到不同模块之间通信出现异常,单独某一个模块的业务日志都没问题,这个时候就想站在使用角度深入了解一下进程通信,记录一下进程通信的使用。


1、进程间通信

进程间通信(IPC,Interprocess communication)是一组编程接口,让程序员能够协调不同的进程,使之能在一个操作系统里同时运行,并相互传递、交换信息。这使得一个程序能够在同一时间里处理许多用户的要求。因为即使只有一个用户发出要求,也可能导致一个操作系统中多个进程的运行,进程之间必须互相通话。IPC接口就提供了这种可能性。每个IPC方法均有它自己的优点和局限性,一般,对于单个程序而言使用所有的IPC方法是不常见的。

进程间通信就是在不同进程之间传播或交换信息。进程的用户空间是互相独立的,一般而言是不能互相访问的,唯一的例外是共享内存区。另外,系统空间是“公共场所”,各进程均可以访问,所以内核也可以提供这样的条件。

常见的通信方式

  • 管道pipe:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。

  • 命名管道FIFO:有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。

  • 消息队列MessageQueue:消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。

  • 共享存储SharedMemory:共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。共享内存有两种实现方式:1、内存映射 2、共享内存机制

  • 信号量Semaphore:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。

  • 套接字Socket:套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。

  • 信号 ( sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。

2、内存映射

mmap属于共享存储内存映射方式进行进程间交互,不同进程通过映射同一个文件,并通过系统调用接口进行读写。mmap提供的这种机制,让进程可以直接访问设备内存(linux目录下的文件),这种机制相比于内核空间和用户空间之间拷贝东西,效率更高。且对于像管道消息队列等通信方式,则需要再内核和用户空间进行四次的数据拷贝,而共享内存则只拷贝两次:一次从输入文件到共享内存区,另一次从共享内存到输出文件。

2.1 常用函数

mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。mmap在用户空间映射调用系统中作用很大。
内存映射常用函数

2.2 映射调试

遇到一个问题,在视频会议中出现没有声音的现象。音频模块查看没有收到音频编码消息,让视频模块定位是否有将该消息透传;视频模块查看,没有从跨芯片队列中收到消息,让媒体系统模块查看;媒体系统模块查看,有将音频的编解码消息发送到跨芯片队列中。这里就出现问题了。
hexdump是Linux下的一个二进制文件查看工具,它可以将二进制文件转换为ASCII、八进制、十进制、十六进制格式进行查看。其使用方式如下

hexdump: [-bcCdovx] [-e fmt] [-f fmt_file] [-n length] [-s skip] [file ...]

hexdump使用方式
使用示例

hexdump -v -n 16040 -C dsp_ctrl > hexdumpall.txt

通过上述指令,将某个被映射的文件通过进制查看工具打印出来。

00000000  00 00 00 00 04 00 00 00  08 00 00 00 0c 00 00 00  |................|		头部40个字节
00000010  a8 3e 00 00 51 00 00 00  51 00 00 00 a0 00 00 00  |.>..Q...Q.......|
00000020  8c 00 00 00 64 00 00 00  [00 00 00 00 02 02 02 00  |....d...........|		前四个字节是状态码,都是0表示正常;
00000030  00 00 0c 00 00 00 00 00  25 00 00 00 00 00 00 00  |........%.......|		后面四个字节是消息号,小端排列00020202;
00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|		这里应该是小端存储,把高字节放在高地址处,低字节
00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|		放在低地址处,[]对应的是一个消息号,160个字节。
00000060  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|		
00000070  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000080  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000090  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000000a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000000b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000000c0  00 00 00 00 00 00 00 00]  00 00 00 00 04 02 02 00  |................|
000000d0  00 00 0c 00 00 00 00 00  02 00 00 00 1e 00 00 00  |................|
000000e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000000f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
.
.
.
00003180  00 00 00 00 00 00 00 00  [00 00 00 00 08 02 02 00  |................|		[00020208]这个消息号是正常的,是字幕控制消息
00003190  01 00 11 00 00 00 00 00  00 00 03 00 00 00 00 00  |................|
000031a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000031b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000031c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000031d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000031e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000031f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00003200  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00003210  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00003220  00 00 00 00 00 00 00 00]  [00 00 00 00 16 02 02 00  |................|		[00020216]这个消息出现异常了,是字幕产生消息
00003230  01 00 11 00 00 00 00 00  31 32 33 34 35 36 37 38  |........12345678|			00 00 00 00 16 02 02 00 对应为状态值四位,消
00003240  31 32 33 34 35 36 37 38  31 32 33 34 35 36 37 38  |1234567812345678|			息码四位;01 00 11 00 00 00 00 00 对应为
00003250  31 32 33 34 35 36 37 38  31 32 33 34 35 36 37 38  |1234567812345678|			dwPara1,dwPara2,剩下的31 32 33 34 35 36 37 
00003260  31 32 33 34 35 36 37 38  31 32 33 34 35 36 37 38  |1234567812345678|			38一共有20组,160个字符,比消息对应的最大长度
00003270  31 32 33 34 35 36 37 38  31 32 33 34 35 36 37 38  |1234567812345678|			128还多,并且能写进去,踩踏了下一个消息的头部
00003280  31 32 33 34 35 36 37 38  31 32 33 34 35 36 37 38  |1234567812345678|
00003290  31 32 33 34 35 36 37 38  31 32 33 34 35 36 37 38  |1234567812345678|
000032a0  31 32 33 34 35 36 37 38  31 32 33 34 35 36 37 38  |1234567812345678|
000032b0  31 32 33 34 35 36 37 38  31 32 33 34 35 36 37 38  |1234567812345678|
000032c0  31 32 33 34 35 36 37 38]  31 32 33 34 35 36 37 38  |1234567812345678|			31 32 33 34 35 36 37 38,这是上一个消息的内
000032d0  31 32 33 34 35 36 37 38  00 00 00 00 00 00 00 00  |12345678........|			容,超过限定长度,踩踏了下一个消息的状态值和消
000032e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|			息号,所以并且应该是音频编解码的消息所以出现了
000032f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|			没有收到音频编码的消息。
00003300  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00003310  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00003320  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

这里可以看到对于消息只有128长度,但是写入了160个字符,所以导致后面的消息头被踩踏,而被踩踏的消息正好是音频编码消息,导致音频模块没有收到音频编码消息,而出现了没有声音的现象

使用指令

media_dump dsp_ctrl	

可以查看跨芯片的规格

_openmap_mpq:unlen:16040
_openmap_mpq:ok m_ubsiz:160
==============================
f0:0
f1:4
f2:8
f3:12

all_size:16040
fill_idx:81
free_idx:81
nod_size:160
nod_size_tag:140
nod_count:100

_fillnod_state:875770417
_freenod_state:875770417		状态码只有1,2,3,加异常四个状态,这种数值就是异常,将该数值转换成16进制,可以查到出问题的内存的内容

3、socket通信

socket
在接收IP摄像头时,我们采用的socket接收udp包,并组包成码流进行编码。阻塞式,阻塞缓存为2M

~、后续

比较零散,后面有机会补上其他进程间通信的案例。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值