操作系统实验报告.docx

上传人:b****1 文档编号:544908 上传时间:2023-04-29 格式:DOCX 页数:22 大小:480.48KB
下载 相关 举报
操作系统实验报告.docx_第1页
第1页 / 共22页
操作系统实验报告.docx_第2页
第2页 / 共22页
操作系统实验报告.docx_第3页
第3页 / 共22页
操作系统实验报告.docx_第4页
第4页 / 共22页
操作系统实验报告.docx_第5页
第5页 / 共22页
操作系统实验报告.docx_第6页
第6页 / 共22页
操作系统实验报告.docx_第7页
第7页 / 共22页
操作系统实验报告.docx_第8页
第8页 / 共22页
操作系统实验报告.docx_第9页
第9页 / 共22页
操作系统实验报告.docx_第10页
第10页 / 共22页
操作系统实验报告.docx_第11页
第11页 / 共22页
操作系统实验报告.docx_第12页
第12页 / 共22页
操作系统实验报告.docx_第13页
第13页 / 共22页
操作系统实验报告.docx_第14页
第14页 / 共22页
操作系统实验报告.docx_第15页
第15页 / 共22页
操作系统实验报告.docx_第16页
第16页 / 共22页
操作系统实验报告.docx_第17页
第17页 / 共22页
操作系统实验报告.docx_第18页
第18页 / 共22页
操作系统实验报告.docx_第19页
第19页 / 共22页
操作系统实验报告.docx_第20页
第20页 / 共22页
亲,该文档总共22页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

操作系统实验报告.docx

《操作系统实验报告.docx》由会员分享,可在线阅读,更多相关《操作系统实验报告.docx(22页珍藏版)》请在冰点文库上搜索。

操作系统实验报告.docx

操作系统实验报告

 

操作系统实验报告

实验三一个进程启动另一个程序的执行

【实验目的】

在Linux环境系统中,execve系统调用用于执行一个程序(可执行二进制文件或脚本)。

exec函数家族,包括execl、execlp、execle、execv、execvp,是execve系统调用的前端。

本实验要求学生学习在一个进程中启动另一个程序执行的基本方法,了解execve系统调用和exec函数家族的使用方法。

【实验内容】

(一)初步认识“在一个进程中启动另一个程序的执行”。

1、编辑一个源程序dummy.c,并编译为可执行程序dummy。

//dummy.c

#include

#include

#include

#include

intmain(intargc,char**argv)

{

intresult;

printf("\nYouarenowinarunningprogram\"%s\".\n",argv[0]);

printf("MyPIDis%d.Myparent'sPIDis%d.\n",getpid(),getppid());

printf(

"Pleaseinputaninteger(0-255),whichwillbereturnedtomyparentprocess:

\n");

scanf("%d",&result);

printf("Goodbye.\n\n");

return(result&0377);

}}

2、再编辑一个源程序exec_test.c,并编译为可执行程序exec_test。

//exec_test.c

#include

#include

#include

#include

#include

#include

intmain(intargc,char**argv)

{

intresult;

result=fork();

if(result<0)

{

perror("Failedtocreatechild");

exit

(1);

}

elseif(result==0)

{

//Child1

char*cmd="./dummy";

printf("Childprocess'sPIDis%d.Myparent'sPIDis%d.\n",getpid(),

getppid());

printf("Childprocessisabouttoexecute\"%s\"\n\n",cmd);

result=execlp(cmd,cmd,NULL);

if(result==-1)

{

perror("Inchildprocess,failedtoexecaprogram");

}

exit(0);

}

else

{

//parent

intstatus;

printf("Parentprocess'sPIDis%d.\n",getpid());

printf("Parentprocessiswaiting...\n");

wait(&status);

printf(

"Inparentprocess,status=0x%x,WEXITSTATUS(status)=%d(i.e.0x%x)\n",\

status,WEXITSTATUS(status),WEXITSTATUS(status));

}

return(EXIT_SUCCESS);

}

3、先执行dummy,观察、分析执行结果;然后执行程序exec_test,观察、分析执行结果。

(注意,两个可执行程序都在当前目录下)

(二)实现一个简单的命令解释外壳(Shell)。

1、基本功能:

(1)从标准输入读取一行字符串,其中包含欲执行的命令和它的命令行参数(如果有的话)。

提示:

需要将输入的一行字符串进行拆分,以空格、制表符(\t)作为分隔符,分解为命令、命令行参数(零个或多个)。

如果用户输入的命令是“quit”,则退出执行。

(2)创建一个子进程。

(3)在子进程中,执行在

(1)读入的命令,如果有命令行参数,也要传递。

(4)在父进程中,等待子进程结束,然后打印子进程的返回值。

(5)在父进程中,控制转移至

(1)。

【实验要求】

按照要求编写程序,放在相应的目录中,编译成功后执行,并按照要求分析执行结果,并写出实验报告。

【实验设计】

dummy程序:

结果显示了该进程的PID和父进程的PID,并且将一个值返回给了父进程。

exec_test程序:

在子进程中键入的数值返回了父进程,并显示了出来(19).

 

实现一个简单的命令解释外壳(Shell)

源代码:

//example

#include

#include

#include

#include

#include

#include

#include

intmain(){

intpid;

intrtn;//子进程的返回值

intexec_errorno;

charcommand[256];

char*p;

char*q;

char*c[20];

inti=0,j=0;

while

(1){

//从终端读取要执行的命令

printf(">");

command[0]='\0';

p=fgets(command,256,stdin);

if(p==NULL){

perror("Errorinfgets().");

exit(-1);

}

//Deletethelastchar(newline)inthestringreturnedbyfgets()

command[strlen(command)-1]='\0';

p=command;

q=p;

//Quitifuserinputs"quit"

if(!

strcmp(command,"quit")){

break;

}

//Createachildprocesstoexecutecommand

pid=fork();

if(pid<0){

perror("Failedwhilecallingfork.");

exit(-1);

}

elseif(pid==0){

//子进程执行此命令

for(;;){

c[i]=strtok(p,"");

if(c[i]==NULL){

break;

}

i++;

p=NULL;

}

p=c[0];

for(j=0;j

printf("%s\n",c[j]);

}

exec_errorno=execvp(p,c);

//如果exec函数返回,表明没有正常执行命令

//只有在这种情况下,才会执行下面的打印错误信息

perror(command);

exit(exec_errorno);

}

else{

//父进程,等待子进程结束,并打印子进程的返回值

wait(&rtn);

printf("\nValuereturnedfromchildprocess,rtn=%d\n",rtn);

printf("WEXITSTATUS(rtn)=%d\n",WEXITSTATUS(rtn));

}

}

return0;

}

【实验测试结果及分析】

此程序通过对execvp()函数的调用,使得通过输入命令被执行。

输入的命令用fgets()存入command字符串中,然后反复调用strtok()函数,分割所得字符串,达到将命令分割的目的,使得多命令行参数得以实现。

【运行结果】

【收获及体会】

实验指导书在实验调试和分析的过程中,我越来越懂得自学能力和自我独立解决问题的重要性。

在以后的实验和学习中,我会不断的加强对这方面的训练。

【参考资料】

实验指导书

实验五线程间的互斥与同步

【实验目的】

理解POSIX线程(Pthread)互斥锁和POSIX信号量机制,学习它们的使用方法;编写程序,实现多个POSIX线程的同步控制。

【实验内容】

创建4个POSIX线程。

其中2个线程(A和B)分别从2个数据文件(data1.txt和data2.txt)

读取10个整数.线程A和B把从文件中读取的逐一整数放入一个缓冲池.缓冲池由n个缓

冲区构成(n=5,并可以方便地调整为其他值),每个缓冲区可以存放一个整数。

另外2个

线程,C和D,各从缓冲池读取10数据。

线程C、D每读出2个数据,分别求出它们的和

或乘积,并打印输出。

提示:

(1)在创建4个线程当中,A和B是生产者,负责从文件读取数据到公共的缓冲区,

C和D是消费者,从缓冲区读取数据然后作不同的计算(加和乘运算)。

使用互斥锁和信

号量控制这些线程的同步。

不限制线程C和D从缓冲区得到的数据来自哪个文件。

(2)在生产者线程中,确保从文件读出数据以后,再去“生产”。

在开始设计和实现之前,务必认真阅读下列内容:

课本6.8.4节;

讲义(课堂PPT)中关于“生产者-消费者问题”的部分;

课本第6章后面的编程项目——生产者-消费者问题。

【实验要求】

按照要求编写程序,放在相应的目录中,编译成功后执行,并按照要求分析执行结果,并写出实验报告。

【实验设计】

#include

#include

#include

#include

#include

#defineNUM_THREADS5

intbuffer[5];

intin=0;//写入标识

intout=0;//读取标识

pthread_mutex_tmutex2in,mutex2out;

sem_twri,rea;

void*write1(void*arg)

{

FILE*fp1=fopen("data1.txt","r");

intw1;

inti1=0;

for(i1=0;i1<10;i1++)

{

//P(写资源)

sem_wait(&wri);

//从文件中读取一个文件

if(fscanf(fp1,"%d",&w1))

;

else

{

printf("I'mthepthreadwrite1,Ican'treadanumfromdata1.txt.\n");

exit

(1);

}

//放入缓存对应位置

//加in锁

pthread_mutex_lock(&mutex2in);

buffer[in]=w1;

in=(in+1)%NUM_THREADS;

//解in锁

pthread_mutex_unlock(&mutex2in);

//V(读资源)

sem_post(&rea);

}

//线程结束

fclose(fp1);

pthread_exit(NULL);

}

 

void*write2(void*arg)

{

intw2;

FILE*fp2=fopen("data2.txt","r");

inti2=0;

for(i2=0;i2<10;i2++)

{

//P(写资源)

sem_wait(&wri);

//从文件中读取一个文件

if(fscanf(fp2,"%d",&w2))

;

else

{

printf("I'mthepthreadwrite1,Ican'treadanumfromdata1.txt.\n");

exit

(1);

}

//放入缓存对应位置

//加in锁

pthread_mutex_lock(&mutex2in);

buffer[in]=w2;

in=(in+1)%NUM_THREADS;

//解in锁

pthread_mutex_unlock(&mutex2in);

//V(读资源)

sem_post(&rea);

}

//线程结束

fclose(fp2);

pthread_exit(NULL);

}

void*plus(void*arg)

{

//加进程

inta1,b1,c1;

intp=0;

for(p=0;p<5;p++)

{

//P(读资源)

sem_wait(&rea);

//从缓冲中读取一个文件

//加out锁

pthread_mutex_lock(&mutex2out);

a1=buffer[out];

out=(out+1)%NUM_THREADS;

//解out锁

pthread_mutex_unlock(&mutex2out);

//V(写资源)

sem_post(&wri);

//P(读资源)

sem_wait(&rea);

//加out锁

pthread_mutex_lock(&mutex2out);

//从缓冲中读取一个文件

b1=buffer[out];

out=(out+1)%NUM_THREADS;

//解out锁

pthread_mutex_unlock(&mutex2out);

c1=a1+b1;

//计算求和并且输出到屏幕

printf("I'mthepthreadofplusing,thisismyresult:

\t%d+%d=%d.\n",

a1,b1,c1);

//V(写资源)

sem_post(&wri);

 

}

//线程结束

pthread_exit(NULL);

}

void*mult(void*arg)

{

//乘进程

inta2,b2,c2;

intp=0;

for(p=0;p<5;p++)

{

//P(读资源)

sem_wait(&rea);

//加out锁

pthread_mutex_lock(&mutex2out);

//从缓冲中读取一个文件

a2=buffer[out];

out=(out+1)%NUM_THREADS;

//解out锁

pthread_mutex_unlock(&mutex2out);

//V(写资源)

sem_post(&wri);

 

//P(读资源)

sem_wait(&rea);

//加out锁

pthread_mutex_lock(&mutex2out);

//从缓冲中读取一个文件

b2=buffer[out];

out=(out+1)%NUM_THREADS;

//解out锁

pthread_mutex_unlock(&mutex2out);

c2=a2*b2;

//计算求积并且输出到屏幕

printf(

"I'mthepthreadofmultiplying,thisismyresult:

\t%d*%d=%d.\n",

a2,b2,c2);

//V(写资源)

sem_post(&wri);

 

}

//线程结束

pthread_exit(NULL);

}

intmain()

{

//互斥锁初始化

pthread_mutex_init(&mutex2in,NULL);

pthread_mutex_init(&mutex2out,NULL);

pthread_tA,B,C,D;

interr;

//信号量初始化

sem_init(&wri,0,5);

sem_init(&rea,0,0);

//创建线程1

err=pthread_create(&A,NULL,write1,NULL);

if(err!

=0)

{

printf("can'tcreatemyThread1:

%s\n",strerror(err));

}

//创建线程2

err=pthread_create(&B,NULL,write2,NULL);

if(err!

=0)

{

printf("can'tcreatemyThread2:

%s\n",strerror(err));

}

//稍微延迟

sleep(0.1);

//创建线程3

err=pthread_create(&C,NULL,plus,NULL);

if(err!

=0)

{

printf("can'tcreatemyThread3:

%s\n",strerror(err));

}

//创建线程4

err=pthread_create(&D,NULL,mult,NULL);

if(err!

=0)

{

printf("can'tcreatemyThread4:

%s\n",strerror(err));

}

pthread_join(A,NULL);

pthread_join(B,NULL);

pthread_join(C,NULL);

pthread_join(D,NULL);

return0;

}

【收获及体会】

在完成上次实验时,我在网上找到了一片相关文章,里面稍有提及互斥锁的知识,当时我粗略看了一下。

没想到这次试验的主体内容就是使用互斥锁和信号量。

简而言之,互斥锁是对互斥资源进行限制访问,以防止不同线程(进程)同时对某个资源进行访问,而导致资源的状态不明,出乎意料,用来实现互斥的。

进而在使用共有资源时,例如本题中的标识量in,out时候,就需要加锁和解锁,以达到在访问in,out时候,只有某一个线程访问此资源,就不会导致资源的状态混乱。

而信号量是用于实现进程同步的,一般是为了使若干线程(进程)之间运行先后有序。

本例中,读取线程一定要在计算线程之前,因而使用信号量,来控制线程之间的先后顺序。

通过本次实验,我也复习了之前学过的一些C语言知识。

包括文件的读取与写入,线程的创建与结束等。

这次实验很有意义,我收获很多。

【参考资料】

实验指导书

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2