system v 共享内存
#include <stdio.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <stdlib.h> int main(){ char *pAddr,*cAddr; int shmid; struct shmid_ds shmbuf; //IPC_PRIVATE:创建新的共享内存 //S_IRUSR|S_IWUSR:写死就行了 //如果要非亲缘进程中使用共享内存 //char *name="/dev/shm/myshm1"; //key_t key = ftok(name,0);name是一个已经存在的文件,0代表是第几个共享内存 //shm_id=shmget(key,4096,IPC_CREAT); shmid=shmget(IPC_PRIVATE,1024,S_IRUSR|S_IWUSR); if(shmid<0){ fprintf(stderr,"shmget error ",strerror(errno)); exit(0); } shmctl(shmid,IPC_STAT,&shmbuf); fprintf(stderr,"shmget->IPC_STAT\t段的大小:%dbyte\t当前附加到该段的进程的个数:%d\t操作的最后1个进程的pid:%d\n",shmbuf.shm_segsz,shmbuf.shm_nattch,shmbuf.shm_lpid); if(fork()){ fprintf(stderr,"父进程%d\n",getpid()); pAddr=(char *)shmat(shmid,0,0); shmctl(shmid,IPC_STAT,&shmbuf); fprintf(stderr,"shmat->IPC_STAT\t段的大小:%dbyte\t当前附加到该段的进程的个数:%d\t操作的最后1个进程的pid:%d\n",shmbuf.shm_segsz,shmbuf.shm_nattch,shmbuf.shm_lpid); strcpy(pAddr,"oooooooooooooooooo"); sleep(3); shmctl(shmid,IPC_STAT,&shmbuf); fprintf(stderr,"shmdt beforce->IPC_STAT\t段的大小:%dbyte\t当前附加到该段的进程的个数:%d\t操作的最后1个进程的pid:%d\n",shmbuf.shm_segsz,shmbuf.shm_nattch,shmbuf.shm_lpid); shmdt(pAddr);//仅仅使pAddr地址无效,实际共享内存并没有释放 shmctl(shmid,IPC_STAT,&shmbuf); fprintf(stderr,"shmdt after->IPC_STAT\t段的大小:%dbyte\t当前附加到该段的进程的个数:%d\t操作的最后1个进程的pid:%d\n",shmbuf.shm_segsz,shmbuf.shm_nattch,shmbuf.shm_lpid); shmctl(shmid,IPC_RMID,&shmbuf);//删除共享内存,如果有其他进程在使用该段内存,则仅标记删除(status=dest),但新进来的shmat会返回失败。 shmctl(shmid,IPC_STAT,&shmbuf); fprintf(stderr,"IPC_RMID->IPC_STAT\t段的大小:%dbyte\t当前附加到该段的进程的个数:%d\t操作的最后1个进程的pid:%d\n",shmbuf.shm_segsz,shmbuf.shm_nattch,shmbuf.shm_lpid); sleep(5); exit(0); }else{ fprintf(stderr,"子进程%d\n",getpid()); sleep(1); shmctl(shmid,IPC_STAT,&shmbuf); fprintf(stderr,"child->IPC_STAT\t段的大小:%dbyte\t当前附加到该段的进程的个数:%d\t操作的最后1个进程的pid:%d\n",shmbuf.shm_segsz,shmbuf.shm_nattch,shmbuf.shm_lpid); //如果要非亲缘进程中使用共享内存 //char *name="/dev/shm/myshm1"; //key_t key = ftok(name,0);name是一个已经存在的文件,0代表是第几个共享内存 //shm_id=shmget(key,4096,IPC_CREAT); cAddr=(char *)shmat(shmid,0,0);//注意,不同进程取到的地址是不一样的 if(cAddr==(void *)-1){ fprintf(stderr,"cAddr null"); exit(0); } shmctl(shmid,IPC_STAT,&shmbuf); fprintf(stderr,"child->shmat IPC_STAT\t段的大小:%dbyte\t当前附加到该段的进程的个数:%d\t操作的最后1个进程的pid:%d\n",shmbuf.shm_segsz,shmbuf.shm_nattch,shmbuf.shm_lpid); fprintf(stderr,"get :%s\n",cAddr); shmctl(shmid,IPC_STAT,&shmbuf); fprintf(stderr,"child->shmdt beforce ->IPC_STAT\t段的大小:%dbyte\t当前附加到该段的进程的个数:%d\t操作的最后1个进程的pid:%d\n",shmbuf.shm_segsz,shmbuf.shm_nattch,shmbuf.shm_lpid); shmdt(pAddr); shmctl(shmid,IPC_STAT,&shmbuf); fprintf(stderr,"child->shmdt after ->IPC_STAT\t段的大小:%dbyte\t当前附加到该段的进程的个数:%d\t操作的最后1个进程的pid:%d\n",shmbuf.shm_segsz,shmbuf.shm_nattch,shmbuf.shm_lpid); shmctl(shmid,IPC_STAT,&shmbuf); fprintf(stderr,"child->IPC_RMID beforce ->IPC_STAT\t段的大小:%dbyte\t当前附加到该段的进程的个数:%d\t操作的最后1个进程的pid:%d\n",shmbuf.shm_segsz,shmbuf.shm_nattch,shmbuf.shm_lpid); shmctl(shmid,IPC_RMID,&shmbuf); shmctl(shmid,IPC_STAT,&shmbuf); fprintf(stderr,"child->IPC_RMID after ->IPC_STAT\t段的大小:%dbyte\t当前附加到该段的进程的个数:%d\t操作的最后1个进程的pid:%d\n",shmbuf.shm_segsz,shmbuf.shm_nattch,shmbuf.shm_lpid); sleep(10); exit(0); } return 0; }