郑州网站设计排行,wordpress联系方式代码,百度指数资讯指数是指什么,无锡网络公司设计IPC 进程间通信方式#xff1a;共享内存
原理
共享内存是最高效的进程间通信方式之一#xff0c;因为它允许两个或多个进程直接访问同一块物理内存区域。这种机制避免了数据在用户空间和内核空间之间的频繁拷贝#xff0c;从而显著提高了数据传输的效率。
在Linux系统中共享内存
原理
共享内存是最高效的进程间通信方式之一因为它允许两个或多个进程直接访问同一块物理内存区域。这种机制避免了数据在用户空间和内核空间之间的频繁拷贝从而显著提高了数据传输的效率。
在Linux系统中共享内存区域由内核管理但可以由多个进程映射到它们各自的地址空间中。这样进程就可以像访问本地内存一样直接读写这块共享内存区域。
操作流程 产生Key值 使用ftok函数根据给定的路径名和项目ID生成一个唯一的键值key这个键值将用于后续的IPC对象操作。 申请共享内存 使用shmget函数根据键值申请一块共享内存区域。如果申请成功该函数会返回一个共享内存标识符shmid。 映射共享内存 使用shmat函数将共享内存区域映射到进程的地址空间中以便进程可以直接访问这块内存。 访问共享内存 进程通过映射得到的地址直接读写共享内存中的数据。 解除映射 使用shmdt函数解除共享内存与进程地址空间的映射关系。 销毁共享内存 当不再需要共享内存时可以使用shmctl函数并指定IPC_RMID命令来删除这块共享内存。
1. ftok - 生成key值
#include sys/types.h
#include sys/ipc.h key_t ftok(const char *pathname, int proj_id);
功能将路径名pathname和工程IDproj_id转换为唯一的key值。参数 pathname一个路径名。proj_id工程ID通常是ASCII字符。返回值成功时返回唯一的key值失败时返回-1。
2. shmget - 申请共享内存
#include sys/ipc.h
#include sys/shm.h int shmget(key_t key, size_t size, int shmflg);
功能使用唯一键值key向内核提出共享内存使用申请。参数 key唯一键值。size要申请的共享内存大小。shmflg访问权限和创建标志如IPC_CREAT、IPC_EXCL。返回值成功时返回共享内存ID失败时返回-1。
3. shmat - 映射共享内存
#include sys/types.h
#include sys/shm.h void *shmat(int shmid, const void *shmaddr, int shmflg);
功能将指定shmid对应的共享内存映射到本地内存。参数 shmid共享内存ID。shmaddr本地地址通常为NULL表示由系统自动分配。shmflg访问权限如0表示读写SHM_RDONLY表示只读。返回值成功时返回映射的地址失败时返回(void*)-1。
4. shmdt - 撤销共享内存映射
#include sys/types.h
#include sys/shm.h int shmdt(const void *shmaddr);
功能将本地内存与共享内存断开映射关系。参数shmaddr要断开的映射地址。返回值成功时返回0失败时返回-1。
5. shmctl - 控制共享内存
#include sys/ipc.h
#include sys/shm.h int shmctl(int shmid, int cmd, struct shmid_ds *buf);
功能修改共享内存属性或删除共享内存对象。参数 shmid共享内存ID。cmd操作命令如IPC_RMID表示删除对象。buf指向shmid_ds结构的指针用于传递信息或NULL仅删除对象时。返回值成功时返回0失败时返回-1。
6.示例
假设我们有两个进程a.out和b.out它们需要通过共享内存交换一个pid_t类型的进程ID。
a.out写进程
#include stdio.h
#include stdlib.h
#include string.h
#include sys/ipc.h
#include sys/shm.h
#include sys/types.h
#include unistd.h int main()
{ key_t key ftok(/tmp, A); int shmid shmget(key, sizeof(pid_t), IPC_CREAT | 0666); if (shmid -1) { perror(shmget); exit(EXIT_FAILURE); } void *shmaddr shmat(shmid, NULL, 0); if (shmaddr (void *)-1) { perror(shmat); exit(EXIT_FAILURE); } pid_t *pid_ptr shmaddr; *pid_ptr getpid(); // 将当前进程的PID写入共享内存 shmdt(shmaddr); shmctl(shmid, IPC_RMID, NULL); return 0;
}
b.out读进程
#include stdio.h
#include stdlib.h
#include sys/ipc.h
#include sys/shm.h
#include sys/types.h
#include unistd.h int main()
{ key_t key ftok(/tmp, A); int shmid shmget(key, sizeof(pid_t), 0666); if (shmid -1) { perror(shmget); exit(EXIT_FAILURE); } void *shmaddr shmat(shmid, NULL, 0); if (shmaddr (void *)-1) { perror(shmat); exit(EXIT_FAILURE); } pid_t *pid_ptr shmaddr; printf(Received PID: %d\n, *pid_ptr); shmdt(shmaddr); return 0;
}
7.总结 共享内存数据的存储方式是拷贝还是剪切 答在共享内存的情况下数据是直接访问的不涉及拷贝或剪切操作。进程直接通过映射的地址访问物理内存区域。 共享内存的数据如果多次不同进程读写会怎么样 答如果多个进程读写同一块共享内存区域并且没有适当的同步机制如信号量那么可能会出现数据竞争和覆盖的情况