程序代码:
sem.h:
1 #ifndef __SEM_H__2 #define __SEM_H__3 4 //创建信号灯集并初始化,semcount表示灯个数5 int open_sem(int semcount);6 7 //申请资源操作,semno表示灯的编号8 int P(int semid,int semno);9 10 //释放资源操作,semno表示灯的编号11 int V(int semid,int semno);12 13 //删除信号灯集14 int del_sem(int semid);15 16 #endif
~
sem.c:
1 #include<myhead.h>2 union semun3 {4 int val;5 struct semid_ds *buf;6 unsigned short *array;7 struct seminfo *__buf;8 };9 //定义给信号灯集中的指定信号灯赋值10 int init_semno(int semid,int semno)11 {12 union semun buf;13 printf("请输入要给编号为%d的灯设置的值:",semno);14 scanf("%d",&buf.val);15 //调用控制函数16 if(semctl(semid,semno,SETVAL,buf)==-1)17 {18 perror("semctl error");19 return -1;20 }21 return 0;22 }23 //创建或打开共享内存,参数为要申请的信号灯集中包含的灯的个数,返回值信号灯集的id24 int open_sem(int semcount)25 {26 //创建key值27 key_t key=-1;28 if((key=ftok("/",'s'))==-1)29 {30 perror("ftok error");31 return -1;32 }33 //通过key值创建一个信号灯集34 int semid=-1;35 if((semid=semget(key,semcount,IPC_CREAT|IPC_EXCL|0664))==-1)36 {37 //对错误码判断,EEXIST,说明信号灯集已存在38 if(errno==EEXIST)39 {40 //直接打开信号灯集即可41 semid=semget(key,semcount,IPC_CREAT|0664);42 return semid;43 }44 perror("semget error");45 return -1;46 }47 //给信号灯集的每个灯进行初始化操作48 for(int i=0;i<semcount;i++)49 {50 //对编号为i的灯进行初始化51 init_semno(semid,i);52 }53 return semid;54 }55 //进行申请资源操作,参数要申请的信号灯id,以及灯的编号56 int P(int semid,int semno)57 {58 //定义要执行操作的结构体变量59 struct sembuf buf;60 buf.sem_num=semno;61 buf.sem_op=-1;//申请资源62 buf.sem_flg=0;//阻塞方式申请63 //执行函数64 if(semop(semid,&buf,1)==-1)65 {66 perror("P error");67 return -1;68 }69 return 0;70 }71 //进行释放资源操作,参数为要申请的信号灯id,以及灯的编号72 int V(int semid,int semno)73 {74 struct sembuf buf;75 buf.sem_num=semno;76 buf.sem_op=1;77 buf.sem_flg=0;78 if(semop(semid,&buf,1)==-1)79 {80 perror("V error");81 return -1;82 }83 return 0;84 }85 //删除信号灯集的操作,参数为要删除的信号灯集86 int del_sem(int semid)87 {88 //删除信号灯集89 if(semctl(semid,0,IPC_RMID)==-1) 90 {91 perror("delete error");92 return -1;93 }94 return 0;95 }
~
shmsnd.c:
1 #include<myhead.h>2 #include "1.h"3 #define PAGE_SIZE 40964 int main(int argc, const char *argv[])5 {6 //11.创建并初始化一个信号灯集7 int semid=open_sem(2);8 //1.创建key值9 key_t key=-1;10 if((key=ftok("/",'k'))==-1)11 {12 perror("ftok error");13 return -1;14 }15 printf("key=%d\n",key);16 //2.将物理内存创建出共享内存段17 int shmid=-1;18 if((shmid=shmget(key,PAGE_SIZE,IPC_CREAT|0664))==-1)19 {20 perror("shmget error");21 return -1;22 }23 printf("shmid=%d\n",shmid);24 //3.将共享内存段地址映射到用户空间25 //NULL表示让系统自动选择页的分段26 //0表示当前进程对共享内存具有读写功能27 char *addr=(char *)shmat(shmid,NULL,0);28 if(addr==(void*)-1)29 {30 perror("shmat error");31 return -1;32 }33 printf("addr=%p\n",addr);34 //4.操作共享内存35 //char buf[128]="";36 while(1)37 {38 //22.申请0号灯的资源39 P(semid,0);40 printf("请输入>>>");41 fgets(addr,PAGE_SIZE,stdin);//从终端输入数据42 addr[strlen(addr)-1]='\0';//将换行换成'\0'43 printf("发送成功\n");44 //33.释放1号灯的资源45 V(semid,1);46 if(strcmp(addr,"quit")==0)47 break;48 }49 //5.取消映射50 if(shmdt(addr)==-1)51 {52 perror("shmdt error");53 return -1;54 }55 //6.删除共享内存56 if(shmctl(shmid,IPC_RMID,NULL)==-1)57 {58 perror("shmctl error");59 return -1;60 }61 return 0;62 }
~
shmrcv:
1 #include<myhead.h>2 #include"1.h"3 #define PAGE_SIZE 40964 int main(int argc, const char *argv[])5 {6 //11.创建信号灯集7 int semid=open_sem(2);8 //1.创建key值9 key_t key=-1;10 if((key=ftok("/",'k'))==-1)11 {12 perror("ftok error");13 return -1;14 }15 printf("key=%d\n",key);16 //2.将物理内存创建共享内存段17 int shmid=-1;18 if((shmid=shmget(key,PAGE_SIZE,IPC_CREAT|0664))==-1)19 {20 perror("shmget error");21 return -1;22 }23 printf("shmid=%d\n",shmid);24 //3.将共享内存段地址映射到用户空间25 //NULL表示让系统自动选择页分段26 //0表示当前进程对共享内存的读写功能27 char *addr=(char*)shmat(shmid,NULL,0);28 if(addr==(void*)-1)29 {30 perror("shmat error");31 return -1;32 }33 printf("addr=%p\n",addr);34 //4.操作共享内存35 //char buf[128]=""; 36 while(1)37 {38 //22.申请1号灯的资源39 P(semid,1);40 printf("共享内存中的数据为:%s\n",addr);41 if(strcmp(addr,"quit")==0)42 break;43 //33.释放0号灯的资源44 V(semid,0);45 }46 //5.取消映射47 if(shmdt(addr)==-1)48 {49 perror("shmdt error");50 return -1;51 }52 //44.删除信号灯集53 del_sem(semid);54 return 0;55 }
~
运行结果: