华工操作系统实验.docx
《华工操作系统实验.docx》由会员分享,可在线阅读,更多相关《华工操作系统实验.docx(29页珍藏版)》请在冰豆网上搜索。
华工操作系统实验
一、实验步骤:
1.在linux下编写一个应用程序,命名为an_ch2_1b。
这个程序不断地输出如下行:
Thoseoutputcomefromchild,[系统时间]
另外写一个应用程序,命名为an_ch2_1a。
这个程序创建一个子进程,执行an_ch2_1b。
这个程序不断地输出如下行:
Thoseoutputcomefromchild,[系统时间]
观察程序运行的结果,并对你看到的现象进行解释。
2.在linux环境下编写一个控制台应用程序,程序中有一个共享的整型变量shared_var,初始值为0;创建一个线程并使其立即与主线程并发执行。
新创建的线程与主线程均不断地循环,并输出shared_var的值。
主线程在循环中不断地对shared_var进行加1操作,即每次循环shared_var被加1;而新创建的线程则不断地对shared_var进行减1操作,即每次循环shared_var被减1。
观察程序运行的结果,并对你看到的现象进行解释。
二、实验数据:
an_ch2_1b.cpp文件:
#include
#include
#include
#include
#include
usingnamespacestd;
stringgetTime()//获取系统时间
{
time_ttimep;
time(&timep);
chartmp[64];
strftime(tmp,sizeof(tmp),"%Y-%m-%d%H:
%M:
%S",localtime(&timep));
returntmp;
}
intmain()
{
while(true)
{
stringtmn=getTime();
cout<<"Thoseoutputcomefromchild,"<sleep
(1);//为了便于截屏使用sleep()函数延迟输出
}
return0;
}
an_ch2_1a.cpp文件:
#include
#include
#include
#include
#include
usingnamespacestd;
intmain()
{
pid_tpid;pid=fork();
if(pid==-1)cout<<"failtocreate"<elseif(pid==0)system("./an_ch2_1b");
return0;
}
Consoleapp.c文件:
#include
#include
#include
#include
intshared_var=0;
void*thread(void*arg)
{
while
(1)
{
printf("inthethreadshared_var:
%d\n",--shared_var);
}
}
intmain()
{
pthread_tpt;
intret=pthread_create(&pt,NULL,(void*)thread,NULL);
if(ret!
=0)printf("failtocreatethread\n");
while
(1)
{
printf("inthemainshared_var:
%d\n",++shared_var);
}
pthread_join(pt,NULL);
return0;
}
1.生产者消费者问题(信号量)
参考教材中的生产者消费者算法,创建5个进程,其中两个进程为生产者进程,3个进程为消费者进程。
一个生产者进程试图不断地在一个缓冲中写入大写字母,另一个生产者进程试图不断地在缓冲中写入小写字母。
3个消费者不断地从缓冲中读取一个字符并输出。
为了使得程序的输出易于看到结果,仿照的实例程序,分别在生产者和消费者进程的合适的位置加入一些随机睡眠时间。
可选的实验:
在上面实验的基础上实现部分消费者有选择地消费某些产品。
例如一个消费者只消费小写字符,一个消费者只消费大写字母,而另一个消费者则无选择地消费任何产品。
消费者要消费的产品没有时,消费者进程被阻塞。
注意缓冲的管理。
2.用线程实现睡觉的理发师问题,(同步互斥方式采用信号量或mutex方式均可)
理发师问题的描述:
一个理发店接待室有n张椅子,工作室有1张椅子;没有顾客时,理发师睡觉;第一个顾客来到时,必须将理发师唤醒;顾客来时如果还有空座的话,他就坐在一个座位上等待;如果顾客来时没有空座位了,他就离开,不理发了;当理发师处理完所有顾客,而又没有新顾客来时,他又开始睡觉。
3.读者写者问题
教材中对读者写者问题算法均有描述,但这个算法在不断地有读者流的情况下,写者会被阻塞。
编写一个写者优先解决读者写者问题的程序,其中读者和写者均是多个进程,用信号量作为同步互斥机制。
1.生产者消费者问题(pro_con.c)
#include
#include
#include
#include
#include
#include
#include
#defineN10//缓冲区大小为100
char*buffer;
intcapacity=N;
sem_tmutex,empty,full;
void*produce_1()
{
while
(1)
{
sem_wait(&empty);
sem_wait(&mutex);
intr1=rand()%26;
intju=0;
for(inti=0;i{
if(buffer[i]=='0')
{
buffer[i]='A'+r1;
printf("生产者1号生产一个产品:
%c剩余容量为:
%d\n",buffer[i],--capacity);
ju=1;
break;
}
}
if(ju==0)printf("没有足够容量!
\n");
sem_post(&mutex);
sem_post(&full);
usleep(r1*100000);
}
}
void*produce_2()
{
while
(1)
{
sem_wait(&empty);
sem_wait(&mutex);
intr2=rand()%26;
intju=0;
for(inti=0;i{
if(buffer[i]=='0')
{
buffer[i]='a'+r2;
printf("生产者2号生产一个产品:
%c剩余容量为:
%d\n",buffer[i],--capacity);
ju=1;
break;
}
}
if(ju==0)printf("没有足够容量!
\n");
sem_post(&mutex);
sem_post(&full);
usleep(r2*100000);
}
}
void*consume_1()
{
while
(1)
{
sem_wait(&full);
sem_wait(&mutex);
intju=0;
for(inti=0;i{
if(buffer[i]>='A'&&buffer[i]<='Z')
{
printf("消费者1号消费一个产品:
%c剩余容量为:
%d\n",buffer[i],++capacity);
buffer[i]='0';
ju=1;
break;
}
}
if(ju==0)printf("没有消费者1号所需的产品!
\n");
sem_post(&mutex);
sem_post(&empty);
intr3=rand()%26;
usleep(r3*100000);
}
}
void*consume_2()
{
while
(1)
{
sem_wait(&full);
sem_wait(&mutex);
intju=0;
for(inti=0;i{
if(buffer[i]>='a'&&buffer[i]<='z')
{
printf("消费者2号消费一个产品:
%c剩余容量为:
%d\n",buffer[i],++capacity);
buffer[i]='0';
ju=1;
break;
}
}
if(ju==0)printf("没有消费者2号所需的产品!
\n");
sem_post(&mutex);
sem_post(&empty);
intr4=rand()%26;
usleep(r4*100000);
}
}
void*consume_3()
{
intju=0;
while
(1)
{
sem_wait(&full);
sem_wait(&mutex);
intju=0;
for(inti=0;i{
if((buffer[i]>='A'&&buffer[i]<='Z')||(buffer[i]>='a'&&buffer[i]<='z'))
{
printf("消费者3号消费一个产品:
%c剩余容量为:
%d\n",buffer[i],++capacity);
buffer[i]='0';
ju=1;
break;
}
}
if(ju==0)printf("没有产品可以消费!
\n");
sem_post(&mutex);
sem_post(&empty);
intr5=rand()%26;
usleep(r5*100000);
}
}
intmain()
{
buffer=(char*)malloc(N*sizeof(char*));
for(inti=0;i{
buffer[i]='0';
}
sem_init(&mutex,1,1);
sem_init(&empty,0,N);
sem_init(&full,0,0);
srand(time(0));
pthread_ttid[5];
pthread_attr_tattr;
pthread_attr_init(&attr);
pthread_create(&tid[0],&attr,produce_1,NULL);
pthread_create(&tid[1],&attr,produce_2,NULL);
pthread_create(&tid[2],&attr,consume_1,NULL);
pthread_create(&tid[3],&attr,consume_2,NULL);
pthread_create(&tid[4],&attr,consume_3,NULL);
for(inti=0;i<5;i++)
{
pthread_join(tid[i],NULL);
}
return0;
}
2.用线程实现睡觉的理发师问题(barber.c)
#include
#include
#include
#include
#include
#include
#defineN5
sem_tcustomer,barber;
intchairs,waiting=0,work=0;
pthread_mutex_tmutex;
void*Barber()
{
printf("无顾客,理发师睡觉\n");
while
(1)
{
sem_wait(&customer);
pthread_mutex_lock(&mutex);
chairs++;
pthread_mutex_unlock(&mutex);
work=1;
printf("理发师正在给一名顾客理发.....%d个顾客正在接待室等待。
\n",--waiting);
sleep
(2);
printf("一名顾客理发完成。
\n");
work=0;
sem_post(&barber);
if(waiting==0)printf("无顾客,理发师睡觉\n");
}
}
void*Customer(void*arg)
{
int*p=(int*)arg;
intx=*p;
pthread_mutex_lock(&mutex);
if(chairs>0)
{
chairs--;
sem_post(&customer);
if(waiting==0&&work==0)
{
printf("第%d个顾客进来,唤醒理发师...\n",++x);
waiting++;
}
elseprintf("第%d个顾客进来,%d个顾客正在接待室等待...\n",x+1,++waiting);
pthread_mutex_unlock(&mutex);
sem_wait(&barber);
}
else
{
pthread_mutex_unlock(&mutex);
printf("第%d个顾客进来,没有座位而离开!
\n",x+1);
}
}
intmain()
{
sem_init(&customer,0,0);
sem_init(&barber,0,1);
chairs=N;
pthread_tbar;
pthread_tcus[N*100];
intcus_id[N*100];
pthread_create(&bar,NULL,Barber,NULL);
inti;
srand(time(0));
for(i=0;i{
usleep(100000*(rand()%30));
cus_id[i]=i;
pthread_create(&cus[i],NULL,Customer,&cus_id[i]);
}
pthread_join(bar,NULL);
for(i=0;i{
pthread_join(cus_id[i],NULL);
}
}
3.读者写者问题(reader_writer.c)
#include
#include
#include
#include
#include
#include
#include
#include
sem_tRWMutex,mutex1,mutex2,mutex3,wrt;
intwriteCount,readCount;
structdata
{
intid;
intlastTime;
};
void*Reader(void*param)
{
intid=((structdata*)param)->id;
intlastTime=((structdata*)param)->lastTime;
printf("读进程%d等待读入\n",id);
sem_wait(&mutex3);
sem_wait(&RWMutex);
sem_wait(&mutex2);
readCount++;
if(readCount==1)sem_wait(&wrt);
sem_post(&mutex2);
sem_post(&RWMutex);
sem_post(&mutex3);
printf("读进程%d开始读入,%d秒后完成\n",id,lastTime);
sleep(lastTime);
printf("读进程%d完成读入\n",id);
sem_wait(&mutex2);
readCount--;
if(readCount==0)sem_post(&wrt);
sem_post(&mutex2);
pthread_exit(0);
}
void*Writer(void*param){
intid=((structdata*)param)->id;
intlastTime=((structdata*)param)->lastTime;
printf("写进程%d等待写入\n",id);
sem_wait(&mutex1);
writeCount++;
if(writeCount==1)sem_wait(&RWMutex);
sem_post(&mutex1);
sem_wait(&wrt);
printf("写进程%d开始写入,%d秒后完成\n",id,lastTime);
sleep(lastTime);
printf("写进程%d完成写入\n",id);
sem_post(&wrt);
sem_wait(&mutex1);
writeCount--;
if(writeCount==0)sem_post(&RWMutex);
sem_post(&mutex1);
pthread_exit(0);
}
intmain()
{
pthread_ttid;
pthread_attr_tattr;
pthread_attr_init(&attr);
sem_init(&mutex1,0,1);
sem_init(&mutex2,0,1);
sem_init(&mutex3,0,1);
sem_init(&wrt,0,1);
sem_init(&RWMutex,0,1);
readCount=writeCount=0;
intid=0;
srand(time(0));
while
(1)
{
introle=rand()%100;
intlastTime=rand()%10;
id++;
structdata*d=(structdata*)malloc(sizeof(structdata));
d->id=id;
d->lastTime=lastTime;
if(role<50)//读
{
printf("创建读进程,PID:
%d\n",id);
pthread_create(&tid,&attr,Reader,d);
}
elseif(role>=50)//写
{
printf("创建写进程,PID:
%d\n",id);
pthread_create(&tid,&attr,Writer,d);
}
sleep(rand()%8);
}
return0;
}
1.实现一个“difftree”命令,其功能是比较两个目录下的文件结构和文件信息。
当在命令行方式下执行“difftree”命令时,能够比较目录dir1和目录dir2是否具有相同的结构,对相同的部分,进一步比较相同文件名的文件内容。
列出比较的文件系统结构图。
本实验是对单个文件比较的扩展,设计中需要考虑目录操作。
difftree.c
#include
#include
#include
#include
#include
#include
#include
intfilelevel1=0,filelevel2=0;
charDIRNAME1[256],DIRNAME2[256];
voidmy_error(constchar*strerr)
{
perror(strerr);
exit
(1);
}
voidfindfile(charfileName1[],chardirentName1[],chardirentName2[])
{
charcommand[512]="diff";
DIR*p_dir=NULL;
structdirent*p_dirent=NULL;
p_dir=opendir(direntName2);
if(p_dir==NULL)
{
my_error("opendirerror");
}
while((p_dirent=readdir(p_dir))!
=NULL)
{
char*backupDirName=NULL;
if(p_dirent->d_name[0]=='.')continue;
inti;
if(p_dirent->d_type==DT_DIR)
{
intcurDirentNameLen=strlen(dirent