1.共享内存(Shared Memory)
定义:
共享内存允许多个进程访问同一块物理内存区域,是 最快 的IPC机制,但需配合同步机制(如信号量)避免竞态条件。
核心特性:
-
零拷贝:数据直接在内存中读写,无需内核中转。
-
高并发性:适合高频数据交换(如视频流处理)。
-
生命周期:随进程分离或显式删除而释放。
-
无内置同步:需开发者自行实现锁或信号量。
操作流程:
-
创建/获取内存段:
shmget
-
附加到进程地址空间:
shmat
-
读写操作:直接操作内存指针。
-
分离内存段:
shmdt
-
删除内存段:
shmctl(..., IPC_RMID)
1.int shmget(key_t key, size_t size, int shmflg); //用来获取或创建共享内存 参数: key:IPC_PRIVATE 或 ftok的返回值 size:共享内存区大小 shmflg:同open函数的权限位,也可以用8进制表示法 返回值: 成功:共享内存段标识符‐‐‐ID‐‐‐文件描述符 出错:‐1
#include<stdio.h> #include <sys/ipc.h> #include <sys/shm.h> int main() { int shmid; shmid=shmget(IPC_PRIVATE,128,0777); if(shmid<0) { printf("creat share memorize failed"); return -1; } printf("creat share memorize success and shmid is %d",shmid); return 0; }
2.void *shmat(int shm_id, const void *shm_addr, int shmflg); //把共享内存连接映射到当前进程的地址空间 参数: shm_id:ID号 shm_addr:映射到的地址,NULL为系统自动完成的映射 shmflg: SHM_RDONLY共享内存只读 默认是0,表示共享内存可读写 返回值: 成功:映射后的地址 失败:NULL
#include<stdio.h> #include <sys/ipc.h> #include <sys/shm.h> #include<stdlib.h> int main() { int shmid; int key; key = ftok("a.c",1); if(key<0) { printf("ftok failed"); return -1; } printf("ftok success\n"); shmid=shmget(key,128,IPC_CREAT|0777); if(shmid<0) { printf("creat share memorize failed"); return -2; } printf("creat share memorize success and shmid is %d\n",shmid); system("ipcs -m"); char *p; p=(char*)shmat(shmid,NULL,0); if(p==NULL) { printf("memorize link failed"); return -3; } printf("memorize link success\n"); printf("in to memorize is:"); //write fgets(p,128,stdin); //read printf("share memorize is %s\n",p); return 0; }
3.int shmdt(const void *shmaddr); //将进程里的地址映射删除 参数: shmid:要操作的共享内存标识符 返回值: 成功:0 出错:‐1 4.int shmctl(int shm_id, int command, struct shmid_ds *buf); //删除共享内存对象 参数: shmid:要操作的共享内存标识符 cmd : IPC_STAT (获取对象属性)‐‐‐ 实现了命令ipcs ‐m IPC_SET (设置对象属性) IPC_RMID (删除对象) ‐‐‐实现了命令ipcrm ‐m buf :指定IPC_STAT/IPC_SET时用以保存/设置属性 返回值: 成功:0 出错:‐1 特点: 1.共享内存创建之后,一直存在于内核中,直到被删除或系统关闭 2.共享内存和管道不一样,读取后,内容仍然在共享内存中
#include<stdio.h> #include <sys/ipc.h> #include <sys/shm.h> #include<stdlib.h> #include<string.h> int main() { int shmid; int key; key = ftok("a.c",1); if(key<0) { printf("ftok failed"); return -1; } printf("ftok success\n"); shmid=shmget(key,128,IPC_CREAT|0777); if(shmid<0) { printf("creat share memorize failed"); return -2; } printf("creat share memorize success and shmid is %d\n",shmid); system("ipcs -m"); char *p; p=(char*)shmat(shmid,NULL,0); if(p==NULL) { printf("memorize link failed"); return -3; } printf("memorize link success\n"); printf("in to memorize is:"); //write fgets(p,128,stdin); //read printf("share memorize is %s\n",p); shmdt(p); // memcpy(p,"hello",5); shmctl(shmid,IPC_RMID,NULL); system("ipcs -m"); return 0; } xiexie@xiexie-virt