Linux进程通信 | 您所在的位置:网站首页 › 进程间通信问题 › Linux进程通信 |
一、共享内存是什么 在Linux系统中,共享内存是一种IPC(进程间通信)方式,它可以让多个进程在物理内存中共享一段内存区域。 这种共享内存区域被映射到多个进程的虚拟地址空间中,使得多个进程可以直接访问同一段物理内存区域中的数据,从而实现进程间的高速数据交换和通信。 二、共享内存的原理共享内存基于内核的支持。在共享内存中,内核维护了一块物理内存区域,并将其映射到多个进程的虚拟地址空间中。每个进程都可以使用指针来访问共享内存区域中的数据,就像它们访问自己的内存一样。 用于创建或打开一个共享内存区段,具体参数如下: 参数类型说明keykey_t共享内存区段的关键字,用于在多个进程间标识同一个共享内存区段。sizesize_t共享内存区段的大小,以字节为单位。shmflgint共享内存区段的访问权限和行为属性。函数返回值为共享内存区段的标识符 shmid,用于标识已创建或已打开的共享内存区段。 shmat函数void *shmat(int shmid, const void *shmaddr, int shmflg);用于将共享内存区段连接到当前进程的地址空间,具体参数如下: 参数类型说明shmidint共享内存区段的标识符,用于标识已创建或已打开的共享内存区段。shmaddrconst void*共享内存区段连接到当前进程地址空间的起始地址,如果为 NULL,则由系统自动选择一个地址。shmflgint标志参数,指定共享内存区段的访问权限和行为属性。函数返回值为共享内存区段连接到当前进程地址空间的起始地址,即指向共享内存区段的指针。 shmdt函数int shmdt(const void *shmaddr);用于断开进程与共享内存区段的连接,具体参数如下: 参数类型说明shmaddrconst void*共享内存区段连接到当前进程地址空间的起始地址。函数返回值为 0 表示成功,-1 表示失败。 shmctl函数int shmctl(int shmid, int cmd, struct shmid_ds *buf);用于控制共享内存区段的行为,如删除、获取、设置共享内存区段的属性等,具体参数如下: 参数类型说明shmidint共享内存区段的标识符,用于标识已创建或已打开的共享内存区段。cmdint控制命令,指定对共享内存区段的操作类型。bufstruct shmid_ds*指向共享内存区段属性结构体的指针,用于获取或设置共享内存区段的属性。常用的cmd参数包括: IPC_STAT:获取共享内存的状态信息,并将该信息存储在buf参数指向的结构体中。IPC_SET:设置共享内存的状态信息,buf参数指向要设置的新值。IPC_RMID:删除共享内存。函数返回值为操作成功返回 0,失败返回 -1。 实例演示以下是一个示例代码,其中一个程序用于写入共享内存,另一个程序用于读取共享内存。 写入程序/* write.c */ #include #include #include #include #include #define SHM_SIZE 1024 int main() { int shmid; char *shmaddr; char write_buf[SHM_SIZE]; // 创建共享内存段 shmid = shmget((key_t)1234, SHM_SIZE, 0666|IPC_CREAT); if (shmid == -1) { perror("shmget failed"); exit(EXIT_FAILURE); } // 将共享内存段连接到当前进程 shmaddr = (char*)shmat(shmid, 0, 0); if (shmaddr == (void*)-1) { perror("shmat failed"); exit(EXIT_FAILURE); } // 从标准输入读取数据并将其写入共享内存 while(1) { fgets(write_buf, SHM_SIZE, stdin); strncpy(shmaddr, write_buf, SHM_SIZE); if (strncmp(write_buf, "exit", 4) == 0) { break; } } // 断开共享内存连接 if (shmdt(shmaddr) == -1) { perror("shmdt failed"); exit(EXIT_FAILURE); } // 删除共享内存段 if (shmctl(shmid, IPC_RMID, 0) == -1) { perror("shmctl failed"); exit(EXIT_FAILURE); } printf("write exit\n"); return 0; }读取程序/* read.c */ #include #include #include #include #include #define SHM_SIZE 1024 int main() { int shmid; char *shmaddr; char read_buf[SHM_SIZE]; // 获取共享内存段 shmid = shmget((key_t)1234, SHM_SIZE, 0666|IPC_CREAT); if (shmid == -1) { perror("shmget failed"); exit(EXIT_FAILURE); } // 将共享内存段连接到当前进程 shmaddr = (char*)shmat(shmid, 0, 0); if (shmaddr == (void*)-1) { perror("shmat failed"); exit(EXIT_FAILURE); } // 从共享内存读取数据并输出到标准输出 while(1) { strncpy(read_buf, shmaddr, SHM_SIZE); printf("Received message: %s\n", read_buf); if (strncmp(read_buf, "exit", 4) == 0) { printf("Received exit\n"); break; } sleep(1); } // 断开共享内存连接 if (shmdt(shmaddr) == -1) { perror("shmdt failed"); exit(EXIT_FAILURE); } printf("read exit\n"); return 0; }编译这两个程序gcc -o write write.c gcc -o read read.c在一个终端窗口中运行write, 输入消息,在另一个终端窗口中运行read,查看消息。 要退出程序,则在运行write的终端窗口中键入"exit",效果如下: 共享内存是一种高效、灵活、方便的进程间通信方式,可以用于在多个进程之间共享大量数据。 使用共享内存需要注意同步、安全和内存泄漏等问题,可以使用信号量、互斥锁等同步机制来保证数据的正确性。 以上,如果觉得对你有帮助,点个赞再走吧,这样@知微之见也有更新下去的动力!也欢迎私信我,一起交流! |
CopyRight 2018-2019 实验室设备网 版权所有 |