嵌入式技术
这次我们来讲一下Linux进程通信中重要的通信方式:共享内存作为Linux软件开发攻城狮,进程间通信是必须熟练掌握的重要技能,而共享内存是在程序开发中常用的也是重要的一种进程间通信方式。
下面我们就来聊一聊Linux下进程间如何实现共享内存通信,有哪些方式?
UNIX和Linux是两种不同的操作系统,它们的主要区别在以下几个方面:
总的来说,UNIX和Linux都是基于UNIX哲学的操作系统,但它们在源代码、可移植性、发行版和命令行工具等方面有所不同。
System V和POSIX是两种不同的操作系统标准,它们的区别在以下几个方面:
System V IPC(Interprocess Communication)和POSIX IPC都是用于在不同进程间进行通信的机制,但它们之间有几个区别:
综上所述,System V IPC和POSIX IPC都有其优点和缺点。 在选择使用哪种IPC机制时,需要根据具体应用场景和需求进行权衡。
在Linux下,共享内存可以使用System V IPC机制或POSIX IPC机制实现。
使用shmget()函数创建共享内存区域并获取其标识符。 使用shmat()函数将共享内存区域附加到进程地址空间中。 使用shmdt()函数将共享内存区域从进程地址空间中分离。 使用shmctl()函数控制共享内存区域的属性和状态。
使用shm_open()函数创建共享内存区域并获取其文件描述符。 使用ftruncate()函数调整共享内存区域的大小。 使用mmap()函数将共享内存区域映射到进程地址空间中。 使用munmap()函数解除共享内存区域与进程地址空间的映射关系。 使用shm_unlink()函数删除共享内存区域的文件名并释放资源。
以下是一个使用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\\n", s8ReadBuf);
#endif
// 分离共享内存区域
if (shmdt(shmaddr) == -1) {
perror("shmdt");
exit(1);
}
return 0;
}
在上面的例程中,我们首先使用ftok()函数生成一个key值作为共享内存的标识符。 然后使用shmget()函数创建共享内存区域,shmaddr指向共享内存区域的起始地址。 最后使用shmdt()函数分离共享内存区域。
以下是一个使用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\\n", 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()函数删除共享内存区域的文件名并释放资源。
通过上面的示例希望对小伙伴们在共享内存通信编程中有所帮助,学会如何使用共享内存通信,并灵活运用于日常的编程中。 共享内存方式的通信必须熟练掌握与应用。
全部0条评论
快来发表一下你的评论吧 !