大连理工大学软件学院操作系统第二次上机.docx
《大连理工大学软件学院操作系统第二次上机.docx》由会员分享,可在线阅读,更多相关《大连理工大学软件学院操作系统第二次上机.docx(23页珍藏版)》请在冰豆网上搜索。
![大连理工大学软件学院操作系统第二次上机.docx](https://file1.bdocx.com/fileroot1/2023-1/2/e100b69c-86b4-4448-bcda-a2ed246a6cc4/e100b69c-86b4-4448-bcda-a2ed246a6cc41.gif)
大连理工大学软件学院操作系统第二次上机
1、代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
/******************定义常量**********************/
#defineSHM_MAX_SIZE80//定义共享内存最大空间
#defineSHM_MODE0600
#defineSEM_MODE0600
#defineMUTEX2
#defineSEM_FULL1
#defineSEM_EMPTY0
/***************const型全局变量*****************/
constintN_CONSUMER=2;
constintN_PRODUCER=1;
constintN_BUFFER=20;//缓冲区容量
constintN_WORKTIME=20;//工作时间
/*****************全局变量*********************/
intshm_id=-1;
intsem_id=-1;
pid_tchild;//子程序ID
pid_tparent;//父程序ID
/******************缓冲区**********************/
structmy_buffer
{
inthead;
inttail;
intstr[SHM_MAX_SIZE/4];
intnum;//缓冲区内的数的个数
intis_empty;
};
/****************生产随机数******************/
intg_random()
{
intrandom;
srand((unsigned)(getpid()+time(NULL)));
random=rand()%10;//0~9随机数
returnrandom;
}
intgetRandomNum()
{
intrandom;
srand((unsigned)(getpid()+time(NULL)));
random=rand()%21;//0~20随机数
returnrandom;
}
/*****************PV操作***********************/
//sem_id指的是信号量集合的ID
//sem_num指的是即将处理的信号量在信号量集合中的索引
//P操作
intwaitSem(intsem_id,intsem_num)
{
structsembufsb;
sb.sem_num=sem_num;
sb.sem_op=-1;//信号量-1
sb.sem_flg=SEM_UNDO;
if(semop(sem_id,&sb,1)<0)
{
perror("waitSemfailed!
\n");
exit
(1);
}
}
//V操作
intsigSem(intsem_id,intsem_num)
{
structsembufsb;
sb.sem_num=sem_num;
sb.sem_op=1;//信号量加1
sb.sem_flg=SEM_UNDO;
if(semop(sem_id,&sb,1)<0)
{
perror("sigSemfailed!
\n");
exit
(1);
}
}
/******************打印结果时间******************/
voidprintTime()
{
time_tnow;
structtm*timenow;
time(&now);
timenow=localtime(&now);
printf("Actualexecutetime:
%s",asctime(timenow));
}
/********************函数主体********************/
intmain()
{
shm_id=shmget(IPC_PRIVATE,SHM_MAX_SIZE,IPC_CREAT|0666);//申请共享内存
if(shm_id<0)//创建失败退出程序
{
perror("Createsharedmemoryfailed!
\n");
exit
(1);
}
structmy_buffer*shmptr;
shmptr=(structmy_buffer*)shmat(shm_id,NULL,1);//连接共享内存和通信进程空间
if(shmptr==(void*)-1)//连接失败退出程序
{
perror("Addbuffertosharedmemoryfailed!
\n");
exit
(1);
}
//创建信号量,失败则退出
if((sem_id=semget(IPC_PRIVATE,3,SEM_MODE))<0)
{
perror("Createsemaphorefailed!
\n");
exit
(1);
}
if(semctl(sem_id,SEM_FULL,SETVAL,0)==-1)
{
perror("Setsemvalueerror!
\n");
exit
(1);
}
if(semctl(sem_id,SEM_EMPTY,SETVAL,20)==-1)
{
perror("Setsemvalueerror!
\n");
exit
(1);
}
if(semctl(sem_id,MUTEX,SETVAL,1)==-1)
{
perror("Setsemvalueerror!
\n");
exit
(1);
}
//设置shmptr的每项数值
shmptr->head=0;
shmptr->tail=0;
shmptr->num=0;
shmptr->is_empty=1;
//生产者部分
parent=fork();
if(parent<0)
{
perror("Producerforkfailed!
\n");
exit
(1);
}
elseif(parent==0)
{
shmptr=shmat(shm_id,0,0);//连接空间至共享内存
if(shmptr==(void*)-1)
{
perror("Addbuffertothesharedmomoryfailed!
\n");
exit
(1);
}
intcount=0;
for(inti=0;i{
waitSem(sem_id,SEM_EMPTY);
waitSem(sem_id,MUTEX);
sleep(g_random());
printf("----------------ProduceprocessNo.%d-------------------\n",i+1);
printf("I'mthepriducer,PID=%d\n",getpid());
//生产
intx=getRandomNum();
shmptr->str[shmptr->tail]=x;
shmptr->tail=(shmptr->tail+1)%SHM_MAX_SIZE;
shmptr->is_empty=0;
shmptr->num++;
//输出生产时间
printTime();
intp;
printf("Thenumberinbufferis%d.\n",shmptr->num+1);
//放入内存
p=(shmptr->tail-1==shmptr->head)?
(shmptr->tail-1):
(shmptr->tail-1+SHM_MAX_SIZE);
for(p;!
(shmptr->is_empty)&&p>=shmptr->head;p--)
{
printf("%d",shmptr->str[p%SHM_MAX_SIZE]);
}
printf("Producerputs%dintothememory!
\n",x);
printf("----------------------No.%dend------------------------\n",i+1);
fflush(stdout);
sigSem(sem_id,MUTEX);
sigSem(sem_id,SEM_FULL);
}
//断开连接
shmdt(shmptr);
exit(0);
}
//消费者程序
for(inti=0;i{
child=fork();
if(child<0)
{
perror("Childforkfailed!
\n");
exit
(1);
}
elseif(child==0)
{
shmptr=shmat(shm_id,0,0);//连接空间至共享内存
if(shmptr==(void*)-1)
{
perror("Addbuffertothesharedmomoryfailed!
\n");
exit
(1);
}
intcount=0;
for(intj=0;j{
waitSem(sem_id,SEM_EMPTY);
waitSem(sem_id,MUTEX);
sleep(g_random());
printf("----------------ConsumerNo.%dprocessNo.%d-----------------\n",i+1,j+1);
printf("I'mtheconsumer,PID=%d\n",getpid());
//输出消费时间
printTime();
if(shmptr->num!
=0)
{
//消费
inty=shmptr->str[shmptr->head];
shmptr->head=(shmptr->head+1)%SHM_MAX_SIZE;
shmptr->is_empty=(shmptr->head==shmptr->tail);
shmptr->num--;
intp;
printf("Thenumberinbufferis%d.\n",shmptr->num+1);
//取出内存
p=(shmptr->tail-1==shmptr->head)?
(shmptr->tail-1):
(shmptr->tail-1+SHM_MAX_SIZE);
for(p;!
(shmptr->is_empty)&&p>=shmptr->head;p--)
{
printf("%d",shmptr->str[p%SHM_MAX_SIZE]);
}
printf("Consumergets%doutofthememory!
\n",y);
}
else
{
printf("Thememoryisempty!
\n");
}
printf("---------------ConsumerN0.%dprocessNo.%dend----------------\n",i+1,j+1);
fflush(stdout);
sigSem(sem_id,MUTEX);
sigSem(sem_id,SEM_EMPTY);
}
//断开连接
shmdt(shmptr);
exit(0);
}
}
//退出主程序
while(wait(0)!
=-1);
//解除连接
shmdt(shmptr);
shmctl(shm_id,IPC_RMID,0);
shmctl(sem_id,IPC_RMID,0);
printf("Exitthemainprocess!
\n");
fflush(stdout);
exit(0);
return0;
}
截图:
2、代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
/******************定义常量**********************/
#defineSHM_MAX_SIZE2//定义共享内存最大空间
#defineSHM_MODE0600
#defineSEM_MODE0600
#defineMUTEX2
#defineSEM_FULL1
#defineSEM_EMPTY0
/***************const型全局变量*****************/
constintN_CONSUMER=2;
constintN_PRODUCER=2;
constintN_BUFFER=2;//缓冲区容量
constintN_WORKTIME=10;//工作时间
/*****************全局变量*********************/
intshm_id=-1;
intsem_id=-1;
pid_tchild;//子程序ID
pid_tparent;//父程序ID
/******************缓冲区**********************/
structmy_buffer
{
inthead;
inttail;
intstr[SHM_MAX_SIZE];
intnum;//缓冲区内的数的个数
intis_empty;
};
/****************生产随机数******************/
intg_random()
{
intrandom;
srand((unsigned)(getpid()+time(NULL)));
random=rand()%10;//0~10随机数
returnrandom;
}
intgetRandomNum()
{
intrandom;
srand((unsigned)(getpid()+time(NULL)));
random=rand()%2;//0~1随机数
returnrandom;
}
/*****************PV操作***********************/
//sem_id指的是信号量集合的ID
//sem_num指的是即将处理的信号量在信号量集合中的索引
//P操作
intwaitSem(intsem_id,intsem_num)
{
structsembufsb;
sb.sem_num=sem_num;
sb.sem_op=-1;//信号量-1
sb.sem_flg=SEM_UNDO;
if(semop(sem_id,&sb,1)<0)
{
perror("waitSemfailed!
\n");
exit
(1);
}
}
//V操作
intsigSem(intsem_id,intsem_num)
{
structsembufsb;
sb.sem_num=sem_num;
sb.sem_op=1;//信号量加1
sb.sem_flg=SEM_UNDO;
if(semop(sem_id,&sb,1)<0)
{
perror("sigSemfailed!
\n");
exit
(1);
}
}
/******************打印结果时间******************/
voidprintTime()
{
time_tnow;
structtm*timenow;
time(&now);
timenow=localtime(&now);
printf("Actualexecutetime:
%s",asctime(timenow));
}
/********************函数主体********************/
intmain()
{
shm_id=shmget(IPC_PRIVATE,SHM_MAX_SIZE*4,IPC_CREAT|0666);//申请共享内存
if(shm_id<0)//创建失败退出程序
{
perror("Createsharedmemoryfailed!
\n");
exit
(1);
}
structmy_buffer*shmptr;
shmptr=(structmy_buffer*)shmat(shm_id,NULL,1);//连接共享内存和通信进程空间
if(shmptr==(void*)-1)//连接失败退出程序
{
perror("Addbuffertosharedmemoryfailed!
\n");
exit
(1);
}
//创建信号量,失败则退出
if((sem_id=semget(IPC_PRIVATE,3,SEM_MODE))<0)
{
perror("Createsemaphorefailed!
\n");
exit
(1);
}
if(semctl(sem_id,SEM_FULL,SETVAL,0)==-1)
{
perror("Setsemvalueerror!
\n");
exit
(1);
}
if(semctl(sem_id,SEM_EMPTY,SETVAL,10)==-1)
{
perror("Setsemvalueerror!
\n");
exit
(1);
}
if(semctl(sem_id,MUTEX,SETVAL,1)==-1)
{
perror("Setsemvalueerror!
\n");
exit
(1);
}
//设置shmptr的每项数值
shmptr->head=0;
shmptr->tail=0;
shmptr->num=0;
shmptr->is_empty=1;
//父亲部分
parent=fork();
if(parent<0)
{
perror("Fatherforkfailed!
\n");
exit
(1);
}
elseif(parent==0)
{
shmptr=shmat(shm_id,0,0);//连接空间至共享内存
if(shmptr==(void*)-1)
{
perror("Addbuffertothesharedmomoryfailed!
\n");
exit
(1);
}
intcount=0;
for(inti=0;i{
waitSem(sem_id,SEM_EMPTY);
waitSem(sem_id,MUTEX);
sleep(g_random());
printf("----------------FatherMakingNo.%d-------------------\n",i+1);
printf("I'mFather,PID=%d\n",getpid());
//生产
intx=getRandomNum();
printf("%d",x);
shmptr->str[shmptr->tail]=x;
shmptr->tail=(shmptr->tail+1)%SHM_MAX_SIZE;
shmptr->is_empty=0;
shmptr->num++;
//输出生产时间
printTime();
intp;
printf("Thenumberoffruitinplantis%d.\n",shmptr->num);
//放入内存
p=(shmptr->tail-1==shmptr->head)?
(shmptr->tail-1):
(shmptr->tail-1+SHM_MAX_SIZE);
if(x==0)
{
printf("Itisappleintheplant.\n");
}
elseif(x==1)
{
printf("Itisorangeintheplant.\n");
}
printf("----------------------No.%dend------------------------\n",i+1);
fflush(stdout);
sigSem(sem_id,MUTEX);
sigSem(sem_id,SEM_FULL);
}
//断开连接
shmdt(shmptr);
exit(0);
}
//儿子女儿程序,0儿子,1女儿
for(inti=0;i{
child=fork();
if(child<0)
{
perror("Childforkfailed!
\n");
exit
(1);
}
elseif(child==0)
{
shmptr=shmat(shm_id,0,0);//连接空间至共享内存
if(shmptr==(void*)-1)
{
perror("Addb