⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 control.c

📁 实现操作系统课程的pv操作
💻 C
字号:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <errno.h>
#include <string.h>
#define SHMKEY1 9075 /*共享存储区的键*/
#define SHMKEY2 9076/*公共变量readcount的存储区的键*/
#define SEMKEY_WRT 9085 /*实现写者之间的互斥和作为第一个读者读的执行条件信号量的键*/
#define SEMKEY_MUTEX 9087 /*对readcount实现互斥修改的互斥信号量的键*/
#define BUFF_LEN 1  /*缓冲区的大小为1*/
#define PRODUCT_LEN 32 /*每个产品是一个字符串:<=32字符*/

void set_sembuf_struct(struct sembuf *sem,int semnum, int semop,int semflg) 
{ 
  /* 设置信号量结构 */ 
  sem->sem_num=semnum; 
  sem->sem_op=semop; 
  sem->sem_flg=semflg; 
} 

main()
{
  char *addr, end;
   int *p;
  int shmid1,shmid2;
  int  semid_wrt, semid_mutex;/*信号量id*/
  struct sembuf sem_tmp;
    
  /*开辟共享存储区*/
  if ((shmid1 = shmget(SHMKEY1, BUFF_LEN * PRODUCT_LEN, 0777|IPC_CREAT|IPC_EXCL)) == -1)
  {
    if (errno == EEXIST)
    {
      printf("缓冲区已经存在!\n");
      printf("你想要删除缓冲区吗?(Y = yes)?\n====:");
      scanf("%c", &end);
      if(end == 'y' || end == 'Y')
      {
      	/* 共享存储区、信号量并不随程序的结束而被删除,如果我们没删除的话, 
        可以用ipcs命令查看,用ipcrm删除 
        */ 
      	/*释放缓冲区*/
      	shmid1 = shmget(SHMKEY1, BUFF_LEN * PRODUCT_LEN, 0777);
      	if (shmctl(shmid1,IPC_RMID,0) < 0)
      	  perror("shmctl:");
          
      	/*同时释放信号量*/   
        semid_mutex = semget(SEMKEY_MUTEX,1, 0777); 
        semid_wrt = semget(SEMKEY_WRT,1, 0777); 
      
        semctl(semid_mutex,0,IPC_RMID);
        semctl(semid_wrt,0,IPC_RMID);
      }
    }
    else 
      printf("创建缓冲区失败!\n");
    return -1;
  }
  if ((shmid2 = shmget(SHMKEY2, sizeof(int), 0777|IPC_CREAT|IPC_EXCL)) == -1)
  {
    if (errno == EEXIST)
    {
      printf("缓冲区已经存在!\n");
      printf("你想要删除缓冲区吗?(Y = yes)?\n====:");
      scanf("%c", &end);
      if(end == 'y' || end == 'Y')
      {
      	/* 共享存储区、信号量并不随程序的结束而被删除,如果我们没删除的话, 
        可以用ipcs命令查看,用ipcrm删除 
        */ 
      	/*释放缓冲区*/
      	shmid2 = shmget(SHMKEY2, sizeof(int), 0777);
      	if (shmctl(shmid2,IPC_RMID,0) < 0)
      	  perror("shmct2:");
          
      	/*同时释放信号量*/   
        
      }
    }
    else 
      printf("创建缓冲区失败!\n");
    return -1;
  }
  
  addr = (char*)shmat(shmid1, 0, 0);/*连接缓冲区*/
  memset(addr, 0, BUFF_LEN * PRODUCT_LEN);
  shmdt(addr); /*离开缓冲区*/
  p=(int*)shmat(shmid2,0,0);
  memset(p,0,sizeof(int));
  *p=0;
  shmdt(p);
  /*创建3个信号量:1个用于对缓冲区互斥,2个用于生产者、消费者同步*/
  if((semid_mutex = semget(SEMKEY_MUTEX,1, 0777|IPC_CREAT|IPC_EXCL))==-1) 
  { 
    if (errno == EEXIST)
      printf("SEMKEY_MUTEX 已经存在!\n");
    else 
      printf("创建 SEMKEY_MUTEX 失败!\n");
    return -1; 
  } 
  
  if((semid_wrt= semget(SEMKEY_WRT,1, 0777|IPC_CREAT|IPC_EXCL))==-1) 
  { 
    if (errno == EEXIST)
      printf("The SEMKEY_WRT 已经存在!\n");
    else 
      printf("创建SEMKEY_WRT失败!\n");
    return -1; 
  } 
  
 
  /*给信号量赋初值*/
  set_sembuf_struct(&sem_tmp, 0, 1, 0);/*BUFF_LEN*/
  semop(semid_wrt, &sem_tmp,1);
  
  set_sembuf_struct(&sem_tmp, 0, 1, 0);/*1*/  
  semop(semid_mutex, &sem_tmp,1);
  
  return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -