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;
}

 

posted on 2017-09-11 13:32  阮減显  阅读(175)  评论(0编辑  收藏  举报

导航