#include<stdio.h>#include<stdlib.h>#include<sys/ipc.h>#include<sys/shm.h>#include<sys/types.h>#include<unistd.h>#include<string.h>#include<sys/sem.h>#defineSHM_SIZE1024//共享内存的大小intmain(intargc,char*argv[]){intret,//临时变量pid,//进程idsme_id,//保存信号量描述符shm_id;//保存共享内存描述符key_tsme_key,//保存信号量键值shm_key;//保存共享内存键值char*shmp;//指向共享内存的首地址structshmid_dsdsbuf;//定义共享内存信息结构变量structsembuflock={0,-1,SEM_UNDO};//信号量上锁操作的数组指针structsembufunlock={0,1,SEM_UNDO|IPC_NOWAIT};//信号量解锁操作的数组指针shm_key=ftok(*(argv+1),2);//获取信号量键值if(shm_key<0){perror("ftok");//调用ftok函数出错exit(0);}sme_id=semget(shm_key,1,IPC_CREAT|0666);//获取信号量IDif(sme_id<0){perror("semget");//调用semget函数出错exit(0);}shm_key=ftok(*(argv+2),1);//获取共享内存键值if(shm_key<0){perror("ftok");exit(0);}shm_id=shmget(shm_key,SHM_SIZE,IPC_CREAT|0666);//获取共享内存IDif(shm_id<0){perror("shmget");exit(0);}shmp=shmat(shm_id,NULL,0);//映像共享内存if((int)shmp==-1){perror("shmat");exit(0);}pid=fork();//创建子进程if(pid<0){perror("fork");exit(0);}elseif(pid==0)//子进程{ret=semctl(sme_id,0,SETVAL,1);//初始化信号量,初值设为1if(ret==-1){perror("semctl");exit(0);}ret=semop(sme_id,&lock,1);//申请访问共享资源,锁定临界资源if(ret==-1){perror("semoplock");exit(0);}sleep(4);//让子进程睡眠4秒strcpy(shmp,"hello\n");//往共享内存写入数据if(shmdt((void*)shmp)<0)//使共享内存脱离进程地址空间{perror("shmdt");}ret=semop(sme_id,&unlock,1);//解锁临界资源if(ret==-1){perror("semopunlock");exit(0);}}else//父进程{sleep(1);//先让子进程运行ret=semop(sme_id,&lock,1);//申请访问共享资源,锁定临界资源if(ret==-1){perror("semoplock");exit(0);}if(shmctl(shm_id,IPC_STAT,&dsbuf)<0)//获取共享内存信息{perror("shmctl");exit(0);}else/*共享内存的状态信息获取成功*/{printf("SharedMemoryInformation:\n");printf("\tCreatorPID:%d\n",dsbuf.shm_cpid);/*输出创建共享内存进程的标识符*/printf("\tSize(bytes):%d\n",dsbuf.shm_segsz);/*输出共享内存的大小*/printf("\tLastOperatorPID:%d\n",dsbuf.shm_lpid);/*输出上一次操作共享内存进程的标识符*/printf("Receivedmessage:%s\n",(char*)shmp);/*从共享内存中读取数据*/}if(shmdt((void*)shmp)<0)//使共享内存脱离进程地址空间{perror("shmdt");exit(0);}ret=semop(sme_id,&unlock,1);//解锁临界资源if(ret==-1){perror("semopunlock");exit(0);}if(shmctl(shm_id,IPC_RMID,NULL)<0)/*删除前面创建的共享内存*/{perror("shmctl");exit(0);}ret=semctl(sme_id,0,IPC_RMID,NULL);//删除信号量if(ret==-1){perror("semctl");exit(0);}}return0;}