共享内存+信号量 实例

    #include<sys/types.h>
  #include<linux/sem.h>
  #include<linux/shm.h>
  #include<unistd.h>
  #include<stdio.h>
  #include<errno.h>
  #include<time.h>
  #define MAXSHM 5  //定义缓冲区数组的下标变量个数

  /*        定义3个信号量的内部标识  */
  int fullid;
  int emptyid;
  int mutexid;

  /* 主函数  */
  int main()
  {
  /*  定义2个共享内存的ID  */
  int arrayid;
  int getid;

  /*  定义共享内存虚拟地址  */
  int *array;
  int *get;

  /* 创建共享内存  */
  arrayid=shmget(IPC_PRIVATE,sizeof(int) *MAXSHN,IPC_CREAT|0666);
  getid=shmget(IPC_PRIVATE,sizeof(int),IPC_CREAT|0666);

  /*  初始化共享内存  */
  array=(int *) shmat(arrayid,0,0);
  get=(int *) shmat(getid,0,0);
  *get=0;

  /* 定义信号量数据结构 */
  struct sembuf  P,V;
  union semun arg;

  /* 创建信号量  */
  fullid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);
  emptyid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);
  mutexid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);

  /*初始化信号量 */
  arg.val=0;            //初始时缓冲区中无数据
  if(semctl(fullid,0,SETVAL,arg)==-1)
  perror(“semctl setval error”);
  arg.val=MAXSHM;       //初始时缓冲区中有5个空闲的数组元素
  if(semctl(emptyid,0,SETVAL,arg)==-1)
  perror(“semctl setval error”);
  arg.val=1;            //初始时互斥信号为1,允许一个进程进入
  if(semctl(mutexid,0,SETVAL,arg)==-1)
  perror(“semctl setval error”);

  /* 初始化 P  V操作  */
  P.sem_num=0;
  P.sem_op=-1;
  P.sem_flg=SEM_UNDO;
  V.sem_num=0;
  V.sem_op=1;
  V.sem_flg=SEM_UNDO;

  /*   生产者进程  */
  if(fork()==0)
  {
  int i=0;
  int set=0;
  while(i<10)
  {
  semop(emptyid,&P,1);         //对 emptyid执行P操作
  semop(mutexid,&P,1);         //对 mutexid执行 P操作
  array[set%MAXSHM]=i+1;
  printf(“Producer put number %d to No.%d\n”,array[set%MAXSHM],set%MAXSHM);
  set++;                       //写计数加1
  semop(mutexid,&V,1);         //对mutexid执行 V 操作
  semop(fullid,&V,1);          //对fullid执行 V 操作
  i++;
  }

  sleep(3);                    //SLEEP 3秒,等待消费者进程执行完毕
  printf(“Poducer if over\n”);
  exit(0);
  }
  else
  {
  /*  消费者A进程  */
  if(fork()==0)
  {
  while(1)
  {
  if(*get==10)
  break;

  semop(fullid,&P,1);        //对fullid执行 P 操作
    semop(mutexid,&P,1);       //对mutexid执行 P 操作
  printf(“The ConsumerA get number from No.%d\n”,(*get)%MAXSHM);
  (*get)++;                   //读计数加1
  semop(mutexid,&V,1);        //对mutexid执行 V 操作
  semop(emptyid,&V,1);        //对fullid执行 V 操作
  sleep(1);
  }
  printf(“ConsunerA is over\n”);
  exit(0);
  }
  else
  {
  /*消费者B进程  */
  if(fork()==0)
  {
  while(1)
  {
  if(*get==10)
  break;
  semop(fullid,&P,1);       //对fullid执行 P 操作
  semop(mutexid,&P,1);      //对mutexid执行 P 操作
  printf(“The ConsumerA get number from No.%d\n”,(*get)%MAXSHM);
  (*get)++;                 //读计数加1
  semop(mutexid,&V,1);      //对mutexid执行 V 操作
  semop(emptyid,&V,1);      //对emptyid执行 V 操作
  sleep(1);
  }
  printf(“ConsunerB is over\n”);
  exit(0);
  }
  }
  }

  /*   父进程返回后回收3个子进程  */
  wait(0);
  wait(0);
  wait(0);
  /*  断开并撤消2个共享内存  */
  shmdt(array);
  shmctl(arrayid,IPC_RMID,0);
  shmctl(get);
  shmctl(getid,IPC_RMID,0);

  /*   撤消3个信号量集  */
  semctl(emptyid,IPC_RMID,0);
  semctl(fullid,IPC_RMID,0);
  semctl(mutexid,IPC_RMID,0);
  exit(0);
  }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值