10.20作业

题目:使用信号灯实现三个进程分别实现abcabcabc

sem.h

#ifndef __SEM_H__
#define __SEM_H__
int init_sem();  //创建并初始化一个信号灯集


int P(int semid,int semnum);          //申请senid信号灯集中的semnum号灯的资源
int V(int semid,int semnum);         //释放semid信号灯集中的semnum号灯的资源
int sem_del(int semid);  //删除信号灯集



#endif

zysem.h 

#include <head.h>
union semun
{
  int val;
  struct semid_ds*buf;
  unsigned short *array;
  struct seminfo *__buf;

};

int init_semnum_value(int semid,int semnum,int value)
{
	//为semctl准备第四个参数,是给信号灯设置值
	union semun s;
	s.val=value;
  if(semctl(semid,semnum,SETVAL,s)==-1)
  {
    perror("semctl error");
	return -1;
  
  }
  return 0;

}




int init_sem()  //创建并初始化一个信号灯集
{
  //创建key值
  key_t key;
  if((key=ftok("./",'k'))==-1)
  {
    perror("ftok error");
	return -1;
  }
  //2创建信号灯集
  int semid;
  if((semid=semget(key,3,IPC_CREAT| IPC_EXCL | 0664))==-1)
  {
	  //对错误码进行判断,如果错误码等于EEXIST

	  if(errno==EEXIST)
	  {
	    semid=semget(key,3,IPC_CREAT|0664);

	  }
	  else
	  {
   perror("semget error");
   return -1;
	  }
	  
  }
  else
  {
  //3初始化信号灯
  //调用自定义函数,为每个灯初始化
  //参数1,要处理的信号灯集id
  //参数2:要处理的信号灯编号
  //参数3:给对应编号的灯初始值/当为1时不会堵塞
   init_semnum_value(semid,0,1);
   init_semnum_value(semid,1,0);
   init_semnum_value(semid,2,0);
  }
   return semid;   //将创建好的信号灯集id返回
}

//申请senid信号灯集中的semnum号灯的资源
int P(int semid,int semnum)
{
	//定义设置灯信息的结构体的变量
	struct sembuf buf;
	buf.sem_num=semnum;   //要处理的信号灯编号
	buf.sem_op=-1;       //表示申请资源

	buf.sem_flg=0;    //阻塞方式申请资源

	
   //将semnum号灯的资源减1操作
     if(semop(semid,&buf,1)==-1)
	 {
	 
	 perror("p  error");
	 return -1;
	 }
	 return 0;
}



int V(int semid,int semnum)         //释放semid信号灯集中的semnum号灯的资源
{

	//定义设置灯信息的结构体的变量
	struct sembuf buf;
	buf.sem_num=semnum;   //要处理的信号灯编号
	buf.sem_op=1;       //表示申请资源

	buf.sem_flg=0;    //阻塞方式申请资源

	
   //将semnum号灯的资源减1操作
     if(semop(semid,&buf,1)==-1)
	 {
	 
	 perror("v  error");
	 return -1;
	 }
	 return 0;
}



int sem_del(int semid)  //删除信号灯集
{
 if(semctl(semid,0,IPC_RMID,0)==-1)
 {
   perror("semctl error");
   return -1;
 }
 return 0;
}



a.c

#include <head.h>
#include "sem.h"    //封装了信号灯集的函数头文件
#define SIZE 4096
int main(int argc, const char *argv[])
{
	//一创建信号灯集并初始化
	int semid;
	if((semid=init_sem())==-1)
	{
	  printf("创建信号灯集失败\n");
	  return -1;
	}



	//1获取key值
	key_t key;
	if((key=ftok("./",'s'))==-1)
	{
	 perror("ftok error");
	 return -1;
	}


   //2创建共享内存
     int shmid;
	 if((shmid=shmget(key,SIZE,IPC_CREAT|0664))==-1)
	{
	 perror("shmget error");
	 return -1;
	}


	//3映射内存地址
	char *addr=shmat(shmid,NULL,0);
	if(addr==(void*)-1)
	{
	  perror("shmat error");
	  return -1;
	}
	printf("addr=%p\n",addr);//输出共享内存的地址

     //循环输入
	 for(int i=1;i<5;i++)
	 {//申请一号灯的资源
		 P(semid,2);

	//向共享内存中写数据
	printf("请输入>>");
	*(char*)addr='a';//直接从终端获取数据到共享内存中
	printf("%c\n",*((char*)addr));
	addr[strlen(addr)-1]=0;
	sleep(1);
            //释放0号等资源(就是释放信号,0可以运行了)
	   V(semid,0);

	   if(strcmp(addr,"quit")==0)
	   {
	      break;
	   }
	 }


	//4取消映射
	if(shmdt(addr)==-1)
	
	{
	 perror("shmdt  error");
	 return -1;
	}
	
	//删除共享内存
	//shmctl(shmid,IPC_RMID,NULL);
	
	//四 删除信号灯集
	//sem_del(semid);
	return 0;
}

b.c

#include <head.h>
#include "sem.h"    //封装了信号灯集的函数头文件
#define SIZE 4096
int main(int argc, const char *argv[])
{
	//一创建信号灯集并初始化
	int semid;
	if((semid=init_sem())==-1)
	{
	  printf("创建信号灯集失败\n");
	  return -1;
	}



	//1获取key值
	key_t key;
	if((key=ftok("./",'k'))==-1)
	{
	 perror("ftok error");
	 return -1;
	}


   //2创建共享内存
     int shmid;
	 if((shmid=shmget(key,SIZE,IPC_CREAT|0664))==-1)
	{
	 perror("shmget error");
	 return -1;
	}


	//3映射内存地址
	char *addr=shmat(shmid,NULL,0);
	if(addr==(void*)-1)
	{
	  perror("shmat error");
	  return -1;
	}
	printf("addr=%p\n",addr);//输出共享内存的地址

     //循环输入
	 for(int i=1;i<5;i++)
	 {//申请一号灯的资源
		 P(semid,0);

	//向共享内存中写数据
	printf("请输入>>");
	*(char*)addr='b';//直接从终端获取数据到共享内存中
	printf("%c\n",*((char*)addr));
	addr[strlen(addr)-1]=0;
   sleep(1);
            //释放0号等资源(就是释放信号,0可以运行了)
	   V(semid,1);

	   if(strcmp(addr,"quit")==0)
	   {
	      break;
	   }
	 }


	//4取消映射
	if(shmdt(addr)==-1)
	
	{
	 perror("shmdt  error");
	 return -1;
	}
	
	//删除共享内存
	//shmctl(shmid,IPC_RMID,NULL);
	
	//四 删除信号灯集
	//sem_del(semid);
	return 0;
}

c.c

#include <head.h>
#include "sem.h"    //封装了信号灯集的函数头文件
#define SIZE 4096
int main(int argc, const char *argv[])
{
	//一创建信号灯集并初始化
	int semid;
	if((semid=init_sem())==-1)
	{
	  printf("创建信号灯集失败\n");
	  return -1;
	}



	//1获取key值
	key_t key;
	if((key=ftok("./",'k'))==-1)
	{
	 perror("ftok error");
	 return -1;
	}


   //2创建共享内存
     int shmid;
	 if((shmid=shmget(key,SIZE,IPC_CREAT|0664))==-1)
	{
	 perror("shmget error");
	 return -1;
	}


	//3映射内存地址
	char *addr=shmat(shmid,NULL,0);
	if(addr==(void*)-1)
	{
	  perror("shmat error");
	  return -1;
	}
	printf("addr=%p\n",addr);//输出共享内存的地址

     //循环输入
	 for(int i=1;i<5;i++)
	 {//申请一号灯的资源
		 P(semid,1);

	//向共享内存中写数据
	printf("请输入>>");
	*(char*)addr='c';//直接从终端获取数据到共享内存中
	printf("%c\n",*((char*)addr));
	addr[strlen(addr)-1]=0;
       sleep(1);
            //释放0号等资源(就是释放信号,0可以运行了)
	   V(semid,2);

	   if(strcmp(addr,"quit")==0)
	   {
	      break;
	   }
	 }


	//4取消映射
	if(shmdt(addr)==-1)
	
	{
	 perror("shmdt  error");
	 return -1;
	}
	
	//删除共享内存
	//shmctl(shmid,IPC_RMID,NULL);
	
	//四 删除信号灯集
	//sem_del(semid);
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值