操作系统实践报告Word格式.docx
《操作系统实践报告Word格式.docx》由会员分享,可在线阅读,更多相关《操作系统实践报告Word格式.docx(24页珍藏版)》请在冰豆网上搜索。
sys/>
#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]='
intj=1;
while(p){
p=strsep(&
if(p){
for(i=0;
dest[j][i]=p[i];
}
dest[j][i]='
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]!
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<
i;
j++){
fseek(fp,0,SEEK_END);
fwrite(comm[j],strlen(comm[j]),1,fp);
fclose(fp);
}else{
comm[j][0]!
printf("
%s"
comm[j]);
printf("
\n"
}else{
intstatus;
wait(&
status);
}elseif(strcmp(comm[0],"
ls"
if(comm[1][0]=='
execlp("
/bin/ls"
"
./"
NULL,NULL,NULL);
comm[1],NULL,NULL,NULL);
cd"
intpid=fork();
if(pid==0){
chdir(comm[1]);
intstatus;
wait(&
system("
exit"
return-1;
return1;
intmain()
while
(1){
charcommand[LEN];
charsplitArray[HEIGHT][WIDTH]={{'
}};
printf("
"
gets(command);
split(command,splitArray);
inti=0;
if(-1==execute(splitArray)){
return0;
实现shell程序,要求在第2版的基础上,添加如下功能
实现管道
$cat/etc/passwd|wc-l
实现管道和文件重定向
$cat
3
2
1
$cat<
|sort|uniq|cat>
首先读取用户输入,以“|”为分隔符将输入分割成字符串数组,然后在一个while循环中依次执行下面的动作:
代码中通过pipe()函数来创建管道,创建之后父进程和子进程一个只能向管道写内容,一个只能向管道读内容。
然后利用dup()函数来把进程的输入流或者输出流重定向到管道里,这样就能实现管道的操作。
实现的时候注意可以使用多个“|”来迭代进行管道操作,需要使用一个循环来处理。
用system执行每一条命令,同时还要注意最后一个操作的输出流是标准输出(即屏幕),不需要重定向到管道里,需要特殊处理一下。
源代码:
|"
main(){
charcommand[LEN];
charsplitArray[HEIGHT][WIDTH]={{'
printf("
gets(command);
split(command,splitArray);
splitArray[i][0]!
puts(splitArray[i]);
intp[2];
pipe(p);
intj=0;
for(j=0;
splitArray[j+1][0]!
if(fork()==0){
.=PI/4
主线程创建1个辅助线程
主线程计算级数的前半部分
辅助线程计算级数的后半部分
主线程等待辅助线程运行结束后,将前半部分和后半部分相加
计算公式前1000项,主线程计算前5000项,子线程计算后5000项,主进程等待子进程结束,通过pthread_join(sub,(void**)&
result);
的result参数获取子进程计算结果再相加即可。
#include<
#defineLEN10000
structresult{
floatsum;
};
void*subThread(){
inti;
floatj;
structresult*result;
floatsum1=0,sum2=0,sum=0;
for(i=LEN/2+1;
i<
=LEN;
j=i;
if(i%2==0){
sum1+=1/(2*j-1);
tart=0;
myparams[0].end=0;
for(i=1;
=thread_num-1;
structparam*myparam;
myparam=&
myparams[i];
myparam->
start=myparams[i-1].end+1;
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;
workers[thread_num-1],NULL,compute,&
myparams[thread_num]);
intj;
floatsum=0;
thread_num-1;
structresult*myresult;
pthread_join(workers[j],(void**)&
myresult);
sum+=myresult->
sum;
free(myresult);
%f\n"
sum);
return0;
多线程排序
主线程创建一个辅助线程
主线程使用选择排序算法对数组的前半部分排序
辅助线程使用选择排序算法对数组的后半部分排序
主线程等待辅助线程运行结束后,使用归并排序算法归并数组的前半部分和后半部分
主线程排序数组的前半部分,辅助线程排序后半部分,pthread_create(&
worker_id,NULL,&
sort,&
pa);
中pa传递的是数组的首地址,主线程等辅助线程结束后,再调用merge将数组合并为有序。
#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;
intmin=0;
inttemp=0;
for(i=LEN/2;
LEN-1;
min=i;
for(j=i;
LEN;
if(mypa->
arr[min]>
mypa->
arr[j])min=j;
temp=mypa->
arr[min];
mypa->
arr[min]=mypa->
arr[i];
arr[i]=temp;
voidmerge(){
inta[LEN/2];
intb[LEN/2];
LEN/2;
a[i]=array[i];
b[i]=array[i+LEN/2];
/*for(i=0;
%d\n"
a[i]);
}*/
inttm=0;
intti=0,tj=0;
while(ti<
LEN/2&
&
tj<
LEN/2){
if(a[ti]<
b[tj]){
array[tm]=a[ti];
ti++;
}else{
array[tm]=b[tj];
tj++;
tm++;
structparampa;
=array;
intti=0,tj=0,tmin=0;
for(ti=0;
ti<
LEN/2-1;
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_join(worker_id,NULL);
merge();
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<
#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()
item=buffer1[out1];
out1=(out1+1)%CAPACITY;
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)
for(i=0;
i<
ITEM_COUNT;
i++){
pthread_mutex_lock(&
mutex2);
while(buffer2_is_empty())
pthread_cond_wait(
&
wait_full_buffer2,
item=get_item();
consumeitem:
%c\n"
item);
sleep
(1);
pthread_cond_signal(&
wait_empty_buffer2);
pthread_mutex_unlock(&
returnNULL;
void*calculate(void*arg)
mutex1);
while(buffer1_is_empty())
&
wait_full_buffer1,
item=cal_get_item();
item+='
A'
-'
wait_empty_buffer1);
while(buffer2_is_full())
pthread_cond_wait(&
wait_empty_buffer2,&
cal_put_item(item);
wait_full_buffer2);
voidproduce()
while(buffer1_is_full())
wait_empty_buffer1,&
item=i+'
produceitem:
put_item(item);
wait_full_buffer1);
pthread_tconsumer_tid;
pthread_tcalculate_tid;
pthread_mutex_init(&
mutex1,NULL);
pthread_cond_init(&
wait_empty_buffer1,NULL);
wait_full_buffer1,NULL);
mutex2,NULL);
wait_empty_buffer2,NULL);
wait_full_buffer2,NULL);
calculate_tid,NULL,calculate,NULL);
consumer_tid,NULL,consume,NULL);
produce();
return0;
使用信号量解决生产者、计算者、消费者问题
功能和前面的实验相同,使用信号量解