1. 程式人生 > >system v 共享內存

system v 共享內存

print usr ftok 新的 byte ipc 共享 err turn

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

system v 共享內存