操作系统实践报告.docx

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

操作系统实践报告.docx

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

操作系统实践报告.docx

操作系统实践报告

操作系统实践报告

 

多进程题目

:

实现shell程序,要求具备如下功能

支持命令参数

$echoarg1arg2arg3

$ls/bin/usr/bin/home

实现内置命令cd、pwd、exit

$cd/bin

$pwd

/bin

思路:

说明:

首先设置一个死循环模仿shell终端,读取用户的输入,并且根据空格将输入拆分成字符串数组,然后调用excute这个子函数进行处理。

1.echo

根据数组第一个元素来判断命令是什么,判断出是ehco后,fork一个新的进程,将其后的内容一个个输出出来,并且父进程等待子进程退出后再执行,确保输出在屏幕上时不被打断。

2.ls

3.读取用户输入并且根据拆分的数组判断出是ls命令后,fork一个新的进程,调用execlp函数将/bin/ls下的ls程序装入子进程并将拆分的数组参数部分传递给ls即可,同样的,父进程等待子进程退出,确保输出在屏幕上不被打断。

4.cd

5.同样是根据输入并拆分成数组后判断出是cd命令后,fork一个新的进程,然后调用chdir并将拆分数组的参数部分传递给chdir作为实参即可。

6.pwd

同样是根据输入并拆分成数组后判断出是pwd命令后,fork一个新的进程,然后调用system("pwd")即可,此命令也可以用来验证上面的cd命令是否正确执行。

7.exit

8.根据用户输入逼格拆分的数组判断出是exit命令后,excute子函数返回-1,在循环中检测excute的返回值,如果是-1则直接return,退出模仿的shell终端。

:

实现shell程序,要求在第1版的基础上,添加如下功能

实现文件重定向

$echohello>log

$catlog

Hello

思路:

接的描述,若判断出是echo命令后,要再次判断拆分的字符串数组中有无“>”出现,如果有,则把“>”之前、echo之后的内容作为输出,把“>”之后到“>”之后的第一个空白字符作为文件名,fopen创建文件并fwrite将输出内容输出到该文件中,并关闭文件。

和的源代码:

#include<>

#include<>

#include<>

#include<>

#include

#include

#include<>

#defineLEN256

#defineWIDTH256

#defineHEIGHT10

voidsplit(charsource[],chardest[HEIGHT][WIDTH])

{

char*p;

p=strsep(&source,"");

inti=0;

for(i=0;p[i]!

='\0';i++){

dest[0][i]=p[i];

}

dest[0][i]='\0';

intj=1;

while(p){

p=strsep(&source,"");

if(p){

for(i=0;p[i]!

='\0';i++){

dest[j][i]=p[i];

}

dest[j][i]='\0';

j++;

}

}

}

intexecute(charcomm[HEIGHT][WIDTH])

{

if(strcmp(comm[0],"echo")==0){

intpid=fork();

if(pid==0){

inti=0;

intis=0;

for(i=1;comm[i][0]!

='\0';i++){

if(comm[i][0]=='>'){

is=1;

break;

}

}

if(is==1){

puts(comm[i+1]);

FILE*fp=fopen(comm[i+1],"w+");

intj=0;

for(j=1;j

fseek(fp,0,SEEK_END);

fwrite(comm[j],strlen(comm[j]),1,fp);

}

fclose(fp);

}else{

intj=0;

for(j=1;comm[j][0]!

='\0';j++){

printf("%s",comm[j]);

printf("");

}

printf("\n");

}

}else{

intstatus;

wait(&status);

}

}elseif(strcmp(comm[0],"ls")==0){

intpid=fork();

if(pid==0){

if(comm[1][0]=='\0'){

execlp("/bin/ls","ls","./",NULL,NULL,NULL);

}else{

execlp("/bin/ls","ls",comm[1],NULL,NULL,NULL);

}

}else{

intstatus;

wait(&status);

}

}elseif(strcmp(comm[0],"cd")==0){

intpid=fork();

if(pid==0){

chdir(comm[1]);

}else{

intstatus;

wait(&status);

}

}elseif(strcmp(comm[0],"pwd")==0){

intpid=fork();

if(pid==0){

system("pwd");

}else{

intstatus;

wait(&status);

}

}elseif(strcmp(comm[0],"exit")==0){

return-1;

}

return1;

}

intmain()

{

while

(1){

charcommand[LEN];

charsplitArray[HEIGHT][WIDTH]={{'\0'}};

printf("%s",">>");

gets(command);

split(command,splitArray);

inti=0;

if(-1==execute(splitArray)){

return0;

}

}

}

:

实现shell程序,要求在第2版的基础上,添加如下功能

实现管道

$cat/etc/passwd|wc-l

实现管道和文件重定向

$cat

3

2

1

3

2

1

$cat<|sort|uniq|cat>

$cat

1

2

3

思路:

首先读取用户输入,以“|”为分隔符将输入分割成字符串数组,然后在一个while循环中依次执行下面的动作:

代码中通过pipe()函数来创建管道,创建之后父进程和子进程一个只能向管道写内容,一个只能向管道读内容。

然后利用dup()函数来把进程的输入流或者输出流重定向到管道里,这样就能实现管道的操作。

实现的时候注意可以使用多个“|”来迭代进行管道操作,需要使用一个循环来处理。

用system执行每一条命令,同时还要注意最后一个操作的输出流是标准输出(即屏幕),不需要重定向到管道里,需要特殊处理一下。

源代码:

#include<>

#include<>

#include<>

#include<>

#include

#include

#include<>

 

#defineLEN256

#defineWIDTH256

#defineHEIGHT10

voidsplit(charsource[],chardest[HEIGHT][WIDTH])

{

char*p;

p=strsep(&source,"|");

inti=0;

for(i=0;p[i]!

='\0';i++){

dest[0][i]=p[i];

}

dest[0][i]='\0';

intj=1;

while(p){

p=strsep(&source,"|");

if(p){

for(i=0;p[i]!

='\0';i++){

dest[j][i]=p[i];

}

dest[j][i]='\0';

j++;

}

}

}

main(){

charcommand[LEN];

charsplitArray[HEIGHT][WIDTH]={{'\0'}};

printf("%s",">>");

gets(command);

split(command,splitArray);

inti=0;

for(i=0;splitArray[i][0]!

='\0';i++){

puts(splitArray[i]);

}

intp[2];

pipe(p);

intj=0;

for(j=0;splitArray[j+1][0]!

='\0';j++){

if(fork()==0){

.=PI/4

主线程创建1个辅助线程

主线程计算级数的前半部分

辅助线程计算级数的后半部分

主线程等待辅助线程运行結束后,将前半部分和后半部分相加

思路:

计算公式前1000项,主线程计算前5000项,子线程计算后5000项,主进程等待子进程结束,通过pthread_join(sub,(void**)&result);的result参数获取子进程计算结果再相加即可。

源代码:

#include<>

#include<>

#include<>

#include<>

#defineLEN10000

structresult{

floatsum;

};

void*subThread(){

inti;

floatj;

structresult*result;

floatsum1=0,sum2=0,sum=0;

for(i=LEN/2+1;i<=LEN;i++){

j=i;

if(i%2==0){

sum1+=1/(2*j-1);

}

tart=0;

myparams[0].end=0;

for(i=1;i<=thread_num-1;i++){

structparam*myparam;

myparam=&myparams[i];

myparam->start=myparams[i-1].end+1;

myparam->end=myparams[i].start+(LEN/thread_num)-1;

pthread_create(&workers[i-1],NULL,compute,myparam);

}

myparams[thread_num].start=myparams[thread_num-1].end+1;

myparams[thread_num].end=LEN;

pthread_create(&workers[thread_num-1],NULL,compute,&myparams[thread_num]);

intj;

floatsum=0;

for(j=0;j

structresult*myresult;

pthread_join(workers[j],(void**)&myresult);

sum+=myresult->sum;

free(myresult);

}

printf("%f\n",sum);

return0;

}

:

多线程排序

主线程创建一个辅助线程

主线程使用选择排序算法对数组的前半部分排序

辅助线程使用选择排序算法对数组的后半部分排序

主线程等待辅助线程运行結束后,使用归并排序算法归并数组的前半部分和后半部分

思路:

主线程排序数组的前半部分,辅助线程排序后半部分,pthread_create(&worker_id,NULL,&sort,&pa);中pa传递的是数组的首地址,主线程等辅助线程结束后,再调用merge将数组合并为有序。

源代码:

#include<>

#include<>

#include<>

#include<>

#defineLEN10

intarray[LEN]={0,3,8,6,2,9,5,4,1,7};

structparam{

int*arr;

};

void*sort(void*arg){

structparam*mypa;

mypa=(structparam*)arg;

inti=0;

intj=0;

intmin=0;

inttemp=0;

for(i=LEN/2;i

min=i;

for(j=i;j

if(mypa->arr[min]>mypa->arr[j])min=j;

}

temp=mypa->arr[min];

mypa->arr[min]=mypa->arr[i];

mypa->arr[i]=temp;

}

}

voidmerge(){

inti=0;

inta[LEN/2];

intb[LEN/2];

for(i=0;i

a[i]=array[i];

b[i]=array[i+LEN/2];

}

/*for(i=0;i

printf("%d\n",a[i]);

}*/

inttm=0;

intti=0,tj=0;

while(ti

if(a[ti]

array[tm]=a[ti];

ti++;

}else{

array[tm]=b[tj];

tj++;

}

tm++;

}

}

intmain()

{

structparampa;

=array;

intti=0,tj=0,tmin=0;

for(ti=0;ti

tmin=ti;

for(tj=ti;tj

if(array[tmin]>array[tj])tmin=tj;

}

inttemp=array[tmin];

array[tmin]=array[ti];

array[ti]=temp;

}

pthread_tworker_id;

pthread_create(&worker_id,NULL,&sort,&pa);

pthread_join(worker_id,NULL);

merge();

inti=0;

for(i=0;i

printf("%d\n",array[i]);

}

}

:

使用条件变量解决生产者、计算者、消费者问题

系统中有3个线程:

生产者、计算者、消费者

系统中有2个容量为4的缓冲区:

buffer1、buffer2

生产者生产'a'、'b'、'c'、‘d'、'e'、'f'、'g'、'h'八个字符,放入到buffer1

计算者从buffer1取出字符,将小写字符转换为大写字符,放入到buffer2

消费者从buffer2取出字符,将其打印到屏幕上

思路:

类似于生产者和消费者,在问题中,生产者、计算者相对应buffer1是生产者、消费者,二者互斥的进入buffer1,并且当buffer1满时,生产者等待,当buffer1空时,且计算值要从中取数据时,计算者等待。

同理,计算者、消费者相对应buffer2是生产者和消费者,二者互斥的进入buffer2,当buffer2满时,且计算者要向其中放入数据时,计算者应等待,当buffer2空时,消费者应等待。

源代码:

#include<>

#include<>

#defineCAPACITY4

intbuffer1[CAPACITY];

intbuffer2[CAPACITY];

intin1;

intout1;

intin2;

intout2;

intbuffer2_is_empty()

{

returnin2==out2;

}

intbuffer2_is_full()

{

return(in2+1)%CAPACITY==out2;

}

intbuffer1_is_empty()

{

returnin1==out1;

}

intbuffer1_is_full()

{

return(in1+1)%CAPACITY==out1;

}

intget_item()

{

intitem;

item=buffer2[out2];

out2=(out2+1)%CAPACITY;

returnitem;

}

voidput_item(intitem)

{

buffer1[in1]=item;

in1=(in1+1)%CAPACITY;

}

intcal_get_item()

{

intitem;

item=buffer1[out1];

out1=(out1+1)%CAPACITY;

returnitem;

}

voidcal_put_item(intitem)

{

buffer2[in2]=item;

in2=(in2+1)%CAPACITY;

}

 

pthread_mutex_tmutex1;

pthread_cond_twait_empty_buffer1;

pthread_cond_twait_full_buffer1;

pthread_mutex_tmutex2;

pthread_cond_twait_empty_buffer2;

pthread_cond_twait_full_buffer2;

#defineITEM_COUNT(CAPACITY*2)

void*consume(void*arg)

{

inti;

intitem;

for(i=0;i

pthread_mutex_lock(&mutex2);

while(buffer2_is_empty())

pthread_cond_wait(

&wait_full_buffer2,

&mutex2);

item=get_item();

printf("consumeitem:

%c\n",item);

sleep

(1);

pthread_cond_signal(&wait_empty_buffer2);

pthread_mutex_unlock(&mutex2);

}

returnNULL;

}

void*calculate(void*arg)

{

inti;

intitem;

for(i=0;i

pthread_mutex_lock(&mutex1);

while(buffer1_is_empty())

pthread_cond_wait(

&wait_full_buffer1,

&mutex1);

item=cal_get_item();

item+='A'-'a';

pthread_cond_signal(&wait_empty_buffer1);

pthread_mutex_unlock(&mutex1);

pthread_mutex_lock(&mutex2);

while(buffer2_is_full())

pthread_cond_wait(&wait_empty_buffer2,&mutex2);

cal_put_item(item);

pthread_cond_signal(&wait_full_buffer2);

pthread_mutex_unlock(&mutex2);

}

returnNULL;

}

voidproduce()

{

inti;

intitem;

for(i=0;i

pthread_mutex_lock(&mutex1);

while(buffer1_is_full())

pthread_cond_wait(&wait_empty_buffer1,&mutex1);

item=i+'a';

printf("produceitem:

%c\n",item);

put_item(item);

sleep

(1);

pthread_cond_signal(&wait_full_buffer1);

pthread_mutex_unlock(&mutex1);

}

}

intmain()

{

pthread_tconsumer_tid;

pthread_tcalculate_tid;

pthread_mutex_init(&mutex1,NULL);

pthread_cond_init(&wait_empty_buffer1,NULL);

pthread_cond_init(&wait_full_buffer1,NULL);

pthread_mutex_init(&mutex2,NULL);

pthread_cond_init(&wait_empty_buffer2,NULL);

pthread_cond_init(&wait_full_buffer2,NULL);

pthread_create(&calculate_tid,NULL,calculate,NULL);

pthread_create(&consumer_tid,NULL,consume,NULL);

produce();

return0;

}

:

使用信号量解决生产者、计算者、消费者问题

功能和前面的实验相同,使用信号量解决

思路:

类似于

源代码:

#include<>

#include<>

#i

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

当前位置:首页 > 经管营销 > 经济市场

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

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