这次我们来讲一下linux进程通信中重要的通信方式:共享内存作为linux软件开发攻城狮,进程间通信是必须熟练掌握的重要技能,而共享内存是在程序开发中常用的也是重要的一种进程间通信方式。
下面我们就来聊一聊linux下进程间如何实现共享内存通信,有哪些方式?
1、基本概念
unix 和 linux
unix和linux是两种不同的操作系统,它们的主要区别在以下几个方面:
历史:unix是最早的商业化操作系统之一,最初由贝尔实验室开发,而linux则是由linus torvalds于1991年开发的开源操作系统。
源代码:unix的源代码是私有的,需要购买授权才能使用和修改,而linux是开源的,任何人都可以自由地访问、使用和修改其源代码。
可移植性:由于unix的代码是私有的,因此它们在不同的硬件平台之间的可移植性较差。而linux的源代码是开放的,因此它可以在多种硬件平台上运行。
发行版:unix有多个商业和非商业版本,如solaris、aix、hp-ux等,每个版本都有自己的特点和功能。而linux则有许多不同的发行版,如ubuntu、debian、red hat、fedora等。
命令行工具:unix和linux有许多相同的命令行工具和命令,如ls、grep、awk等,但也有一些不同之处。
总的来说,unix和linux都是基于unix哲学的操作系统,但它们在源代码、可移植性、发行版和命令行工具等方面有所不同。
system v 和 posix
system v和posix是两种不同的操作系统标准,它们的区别在以下几个方面:
历史背景:system v最初是由at&t开发的unix版本,而posix是ieee为了保证不同unix系统的兼容性而开发的标准。
体系结构:system v是一种具体的操作系统,而posix则是一种操作系统接口标准。因此,system v具有更多的操作系统特定功能,而posix的接口更为通用,适用于多种不同类型的unix系统。
文件系统:system v和posix的文件系统不同。system v使用名为“inode”的数据结构来描述文件和目录,而posix则使用名为“文件描述符”的整数来表示打开的文件。
shell:system v和posix的shell也不同。system v的shell是bourne shell,而posix的shell是bourne-again shell(bash)。
网络支持:system v和posix的网络支持也不同。system v使用tcp/ip协议栈,而posix使用套接字(socket)接口。
2、system v ipc 和 posix ipc
system v ipc(interprocess communication)和posix ipc都是用于在不同进程间进行通信的机制,但它们之间有几个区别:
编程接口:system v ipc和posix ipc的编程接口不同。system v ipc使用ipc对象(如信号量、共享内存和消息队列)来实现进程间通信,而posix ipc使用命名对象(如命名信号量、命名共享内存和命名管道)。
可移植性:posix ipc是由ieee posix标准定义的,因此posix ipc是可移植的,可在不同的操作系统上使用。而system v ipc是由system v操作系统提供的,因此不同的操作系统可能实现不同,因此在跨平台时可能会有问题。
接口和实现:system v ipc的接口和实现是紧密耦合的,而posix ipc的接口和实现是松散耦合的。这意味着在posix ipc中,接口和实现是独立的,因此可以在实现中进行更改,而不影响接口,这使得在不同的系统上实现相同的接口变得更容易。
特性:system v ipc提供的特性比posix ipc多,例如,system v ipc提供了消息队列,而posix ipc则没有。另一方面,posix ipc提供了诸如命名管道之类的特性,而system v ipc则没有。
综上所述,system v ipc和posix ipc都有其优点和缺点。在选择使用哪种ipc机制时,需要根据具体应用场景和需求进行权衡。
3、共享内存实现方式
在linux下,共享内存可以使用system v ipc机制或posix ipc机制实现。
使用system v ipc机制:
使用shmget()函数创建共享内存区域并获取其标识符。使用shmat()函数将共享内存区域附加到进程地址空间中。使用shmdt()函数将共享内存区域从进程地址空间中分离。使用shmctl()函数控制共享内存区域的属性和状态。
使用posix ipc机制:
使用shm_open()函数创建共享内存区域并获取其文件描述符。使用ftruncate()函数调整共享内存区域的大小。使用mmap()函数将共享内存区域映射到进程地址空间中。使用munmap()函数解除共享内存区域与进程地址空间的映射关系。使用shm_unlink()函数删除共享内存区域的文件名并释放资源。
system v ipc机制实现共享内存
以下是一个使用system v ipc机制实现共享内存的简单例程,它展示了如何创建、附加和分离共享内存区域。
#include #include #include #include #include #define shm_size 1024 // 共享内存大小int main() { int shmid; char *shmaddr; char s8readbuf[1024] = {0}; key_t key = ftok(., 's'); // 获取共享内存标识符 if (key == -1) { perror(ftok); exit(1); } // 创建共享内存区域 shmid = shmget(key, shm_size, ipc_creat | 0666); if (shmid == -1) { perror(shmget); exit(1); } // 将共享内存区域附加到进程地址空间中 shmaddr = shmat(shmid, null, 0); if (shmaddr == (char *) -1) { perror(shmat); exit(1); }#if 1 // 在共享内存中写入数据 strncpy(shmaddr, hello, world!, shm_size);#else // 读数据 // memcpy(s8readbuf, shmaddr, 1024); // printf(s8readbuf:%s, s8readbuf);#endif // 分离共享内存区域 if (shmdt(shmaddr) == -1) { perror(shmdt); exit(1); } return 0;} 在上面的例程中,我们首先使用ftok()函数生成一个key值作为共享内存的标识符。然后使用shmget()函数创建共享内存区域,shmaddr指向共享内存区域的起始地址。最后使用shmdt()函数分离共享内存区域。
posix ipc机制实现共享内存
以下是一个使用posix ipc机制实现共享内存的简单例程,它展示了如何创建、映射和解除映射共享内存区域。
#include #include #include #include #include #include #define shm_size 1024 // 共享内存大小#define shm_name /myshm // 共享内存名称int main() { int fd; char *shmaddr; char s8readbuf[1024] = {0}; const char *msg = hello, world!; // 创建共享内存区域 fd = shm_open(shm_name, o_creat | o_rdwr, 0666); if (fd == -1) { perror(shm_open); exit(1); } // 调整共享内存区域的大小 if (ftruncate(fd, shm_size) == -1) { perror(ftruncate); exit(1); } // 映射共享内存区域到进程地址空间中 shmaddr = mmap(null, shm_size, prot_read | prot_write, map_shared, fd, 0); if (shmaddr == map_failed) { perror(mmap); exit(1); }#if 1 // 在共享内存中写入数据 strncpy(shmaddr, msg, shm_size);#else // 读数据 // memcpy(s8readbuf, shmaddr, 1024); // printf(s8readbuf:%s, s8readbuf);#endif // 解除共享内存区域与进程地址空间的映射关系 if (munmap(shmaddr, shm_size) == -1) { perror(munmap); exit(1); } // 删除共享内存区域的文件名并释放资源 if (shm_unlink(shm_name) == -1) { perror(shm_unlink); exit(1); } return 0;} 在上面的例程中,我们使用shm_open()函数创建一个共享内存区域,然后使用ftruncate()函数调整共享内存区域的大小。接着,我们使用mmap()函数将共享内存区域映射到进程地址空间中,并使用strncpy()函数在共享内存中写入数据。最后,我们使用munmap()函数解除共享内存区域与进程地址空间的映射关系,并使用shm_unlink()函数删除共享内存区域的文件名并释放资源。
小结
通过上面的示例希望对小伙伴们在共享内存通信编程中有所帮助,学会如何使用共享内存通信,并灵活运用于日常的编程中。共享内存方式的通信必须熟练掌握与应用。
监控无线网桥安装图解
【大大芯方案】高效节能更省电,大联大推出基于NXP产品的永磁同步电机驱动方案
越南接轨全球最低税负制,影响三星、英特尔布局
拼多多拟再融资逾10亿美金 蓄力“新品牌计划”及农产品上行
三星面板供应过剩_拟暂停韩国LCD面板产线
Linux进程间如何实现共享内存通信
SiC器件相对于Si器件的优势有什么
纯电动轿车的汽车电子成本将达到整车成本的65%
一文汇总消费电子_物联网与半导体电子行业供应链厂商
数字中国建设规划出炉 科技产业迎新契机
电子芯闻早报:机器人崛起,Windows 10相随
艾迈斯半导体的光谱传感器能够通过频谱解析,可靠读取病毒颗粒
塑胶件设计一般步骤,塑胶零件常须解决的问题等方面解析
STM32CubeIDE免费供用户使用 高度集成提供众多高端功能
基于方寸T620国密安全芯片的视频加密安全传输解决方案
钒电池的发展历程及工作原理
la7845引脚功能及各管脚电压
Bitwise向SEC提交了一份文件要求撤回比特币ETF的申请
优化pcb布局会带来什么好处
中国该如何打造自己的人工智能基础教育?