面试题答案
一键面试数据交互挑战
- 指针问题:不同进程逻辑地址空间相互独立,在一个进程中的指针,对另一个进程毫无意义。若共享内存中存放指针,接收方无法直接使用该指针访问数据。
- 数据结构对齐差异:不同进程可能因编译器、操作系统设置等原因,对数据结构对齐方式不同。这可能导致在一个进程中正确填充和布局的数据结构,在另一个进程中解析错误。
解决方案
- 使用序列化与反序列化
- 原理:将需要共享的数据转换为字节流形式,这个过程称为序列化。接收方收到字节流后,再将其恢复为原来的数据结构,即反序列化。这样就避免了因逻辑地址不同和数据结构对齐差异带来的问题,因为传递的只是数据的字节表示,不涉及进程内的逻辑地址。
- 实现要点:
- 选择合适的序列化库,如Protocol Buffers、JSON等。以Protocol Buffers为例,首先要定义数据结构的.proto文件,通过工具生成对应的C++代码。在发送方,创建数据对象并填充数据,然后调用生成代码中的序列化函数将其转换为字节流发送。在接收方,接收到字节流后,调用反序列化函数恢复数据对象。
- 注意数据类型的兼容性,确保序列化和反序列化使用相同的规则和数据类型定义。
- 共享内存结合偏移量
- 原理:在共享内存中不直接存放指针,而是使用偏移量。发送方将数据放入共享内存,并记录数据在共享内存中的偏移位置。接收方根据这个偏移量在共享内存中访问数据,从而绕开逻辑地址不同的问题。
- 实现要点:
- 使用系统调用(如POSIX共享内存函数shmget、shmat等)创建和映射共享内存。
- 发送方在共享内存中分配空间存放数据,并计算数据相对于共享内存起始地址的偏移量,将偏移量通过某种方式(如管道、消息队列等)传递给接收方。
- 接收方获取偏移量后,结合共享内存起始地址,就可以访问到数据。同时要注意共享内存的同步访问问题,可使用信号量等机制进行同步。