操作系统实验报告线程并发拷贝程序.docx

上传人:b****5 文档编号:6144431 上传时间:2023-01-04 格式:DOCX 页数:16 大小:18.36KB
下载 相关 举报
操作系统实验报告线程并发拷贝程序.docx_第1页
第1页 / 共16页
操作系统实验报告线程并发拷贝程序.docx_第2页
第2页 / 共16页
操作系统实验报告线程并发拷贝程序.docx_第3页
第3页 / 共16页
操作系统实验报告线程并发拷贝程序.docx_第4页
第4页 / 共16页
操作系统实验报告线程并发拷贝程序.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

操作系统实验报告线程并发拷贝程序.docx

《操作系统实验报告线程并发拷贝程序.docx》由会员分享,可在线阅读,更多相关《操作系统实验报告线程并发拷贝程序.docx(16页珍藏版)》请在冰豆网上搜索。

操作系统实验报告线程并发拷贝程序.docx

操作系统实验报告线程并发拷贝程序

操作系统:

线程(进程)并发拷贝程序

附录一:

程序代码

#include

#include

#include

#include

#include

#include

#include

#definePSIZE4096/*管道文件的大小*/

#defineBSIZE128/*默认缓冲区的大小*/

#defineNOFILE20/*u_ofile3575表可分配的个数*/

#defineNFILE20/*file表可分配的个数*/

#defineNPIPE20/*pipecb3575可分配的个数*/

/*进程的u_file表*/

intu_ofile3575[NOFILE];

/*模拟file表*/

struct

{

charf_flag;/*读写标志,'w'表示写,'r'表示读*/

intf_count;/*表示此表项的状态,=0表示此表项没被使用,可分配;=1表示此表项在被使用,不可再分配*/

intf_inode;/*对应的pipecb3575表下标*/

longf_offset;/*读写指针,当前已读或已写个数*/

}file[NFILE];

/*管道控制块*/

struct

{

char*p_addr;/*管道文件基地址*/

intp_size;/*管道文件大小,PSIZE*/

intp_count;/*=2表示读写都在被进行,=1表示在被读或被写,=0表示管道没被使用,可分配*/

}pipecb3575[NPIPE];

/*模拟管道文件*/

char*pfile;

/*管道的写入写出端*/

intfd[2];

/*锁机制,实现互斥*/

pthread_mutex_tlock=PTHREAD_MUTEX_INITIALIZER;

/*进程间通信,实现同步*/

pthread_cond_trflag=PTHREAD_COND_INITIALIZER;/*读信号量*/

pthread_cond_twflag=PTHREAD_COND_INITIALIZER;/*写信号量*/

/*线程创建函数只能传一个参数,用结构体来封装所有参数*/

structarg_set

{

char*fname;/*文件名*/

intf;/*传递fdp[]*/

};

/*u_ofile3575表初始化*/

intu_ofile_init3575()

{

printf("inittheu_ofile3575\n");

inti;

for(i=0;i

u_ofile3575[i]=-1;

u_ofile3575[0]=0;

u_ofile3575[1]=0;

u_ofile3575[2]=0;

return0;

}

/*创建管道*/

intpipe_simulate3575(inta[])

{

printf("starttocreateapipe\n");

inti;

for(i=0;i

{

if(u_ofile3575[i]==-1)

{

a[0]=i;/*读*/

u_ofile3575[i]=0;/*读端*/

break;

}

}

for(i;i

{

if(u_ofile3575[i]==-1)

{

a[1]=i;/*写*/

u_ofile3575[i]=1;/*写端*/

break;

}

}

if(i>=NOFILE)

{

printf("u_ofile3575分配失败,failuretocreateapipe\n");

return-2;

}

pfile=(char*)malloc(PSIZE*sizeof(char));/*申请模拟管道用的内存空间*/

if(pfile==NULL)/*申请可能不成功*/

{

printf("failuretocreateapipe\n");

return-1;

}

for(i=0;i

{

if(file[i].f_count!

=1)

{

file[i].f_flag='r';/*读标志*/

//file[i].f_inode=0;/*读对应pipecb3575表下标*/

file[i].f_count=1;/*file[0]这个表项在被使用,不可再分配*/

file[i].f_offset=0;/*读指针*/

u_ofile3575[a[0]]=i;/*读端*/

break;

}

}

for(i=0;i

{

if(file[i].f_count!

=1)

{

file[i].f_flag='w';/*写标志*/

//file[i].f_inode=0;/*写对应pipecb3575控制块下标*/

file[i].f_count=1;/*file[1]这个表项在被使用,不可再分配*/

file[i].f_offset=0;/*写指针*/

u_ofile3575[a[1]]=i;/*写端*/

break;

}

}

if(i>=NFILE)

{

printf("failuretocreateapipe\n");

return-1;

}

for(i=0;i

{

if(pipecb3575[i].p_count==0)

{

pipecb3575[i].p_addr=pfile;/*给管道文件基地址赋值*/

pipecb3575[i].p_size=PSIZE;/*管道文件大小*/

pipecb3575[i].p_count=2;/*读写都在进行,此pipecb3575表项不可再分*/

file[u_ofile3575[a[0]]].f_inode=i;

file[u_ofile3575[a[1]]].f_inode=i;

break;

}

}

if(i>=NPIPE)

{

printf("failuretocreateapipe\n");

return-1;

}

printf("Secceedcreatethepipe\n");

return0;/*分配成功*/

}

/*关闭管道*/

intclose_simulate3575(inta[])

{

printf("starttoclosethepipeyouhavecreated\n");

char*p;

inti;

for(i=0;i<2;i++)

{

p=pipecb3575[file[u_ofile3575[a[i]]].f_inode].p_addr;

/*

if(p!

=NULL)

free(p);//释放管道内存

*/

pipecb3575[file[u_ofile3575[a[i]]].f_inode].p_count=0;/*管道控制块计数清零*/

file[u_ofile3575[a[i]]].f_count=0;/*file表项计数清零*/

u_ofile3575[a[i]]=-1;/*u_ofile3575表项清空*/

a[i]=-1;/*fdp[]清空?

*/

}

printf("secceedclosethepipe\n");

return0;

}

/*写管道*/

intnumwrite_simulate3575;

intwrite_simulate3575(intfd,char*ca,intn)//将内存ca内容写入n个字符到管道fd里

{

printf("(memory---->pipe)inputdatainmemory*caintopipe\n");

numwrite_simulate3575++;

longoffr,offw;/*读写指针,实际是读写字符个数*/

intr;/*管道文件读端*/

intm;/*若ca中的字符不能一次写完,m用来表示一次可写入的字符的最大数*/

intw=u_ofile3575[fd];/*管道文件写端*/

intpf=file[w].f_inode;/*读管道对应的pipecb3575表的下标*/

intn1=n;/*一次应该写入的字符个数*/

intwstart=0;/*计数器,写入字符个数*/

inti=0;

for(i;i

{

if((file[i].f_flag=='r')&&(file[i].f_inode==pf))

{

r=i;

break;

}

else

{

continue;

}

}

printf("----addthelock\n");

pthread_mutex_lock(&lock);/*互斥锁,相当于进入临界区*/

offr=file[r].f_offset;/*赋值读指针*/

offw=file[w].f_offset;/*赋值写指针*/

if((offw+n1-PSIZE)>offr)/*不能一次写完*/

{

if(pipecb3575[pf].p_count==0)/*对文件的复制操作已进行结束,管道文件被释放*/

{

printf("对文件的复制操作已进行结束,管道文件被释放\n");

return0;

}

else

{

m=PSIZE+offr-offw;/*最多可写入数*/

for(wstart=0;wstart

{

*(pipecb3575[pf].p_addr+offw%PSIZE)=*ca;

ca++;

offw++;

}

file[w].f_offset=offw;/*重定位写指针位置*/

n1=n1-m;/*剩余需要读的字符个数*/

printf("weakupthereadthread,pipeisreadable\n");

pthread_cond_signal(&rflag);/*唤醒读线程,管道可读*/

printf("writethreadisblockedandunderthestatementofwaiting\n");

pthread_cond_wait(&wflag,&lock);/*写线程封锁等待*/

}

}

/*一次性可将ca中内容全部写入管道*/

offr=file[r].f_offset;

offw=file[w].f_offset;

for(wstart=0;wstart

{

/*printf("%d\n",pipecb3575[pf].p_addr);*/

*(pipecb3575[pf].p_addr+offw%PSIZE)=*ca;

/*printf("%d\n",wstart);*/

ca++;

offw++;

}

file[w].f_offset=offw;

pthread_cond_signal(&rflag);

printf("----releasethelock\n");

pthread_mutex_unlock(&lock);

printf("Secceed(memory---->pipe)inputdatainmemory*caintopipe\n");

returnn;/*返回写入字符个数*/

}

/*读管道*/

intnumread_simulate3575;//read_simulate3575diaoyongshu

intread_simulate3575(intfd,char*ca,intn)//将管道fd内容读取n个字符到内存ca里

{

printf("(pipe---->memory)outputdatafrompipeintomemory*ca\n");

numread_simulate3575++;

longoffr,offw;/*读写指针,实际是读写字符个数*/

intw;/*管道文件写端*/

intm;/*若ca中的字符不能一次读完,m用来表示一次可读出的字符的最大数*/

intr=u_ofile3575[fd];/*管道文件读端*/

intpf=file[r].f_inode;/*读管道对应的pipecb3575表的下标*/

intrstart=0;/*计数器,读出字符个数*/

inti=0;

for(i;i

{

if((file[i].f_flag=='w')&&(file[i].f_inode==pf))

{

w=i;

break;

}

else

{

continue;

}

}

printf("----addthelock\n");

pthread_mutex_lock(&lock);/*互斥锁,相当于进入临界区*/

offr=file[r].f_offset;/*赋值读指针*/

offw=file[w].f_offset;/*赋值写指针*/

if(offr==offw)/*管道空,无内容可读*/

{

printf("pipeisempty,nothingtooutput\n");

if(pipecb3575[pf].p_count==1)/*写端关闭*/

{

pipecb3575[pf].p_count--;/*文件的复制以完成,释放管道文件的空间*/

printf("thewritepointisclosed,thecopyofthefileisfinished\n");

return0;

}

else

{

printf("weakupthewritethread,makethepipewritable\n");

pthread_cond_signal(&wflag);/*唤醒写线程,管道可写*/

printf("readthreadisblockedandunderthestatementofwaiting\n");

pthread_cond_wait(&rflag,&lock);/*读线程封锁等待*/

}

}

offr=file[r].f_offset;

offw=file[w].f_offset;

m=n<=(offw-offr)?

n:

(offw-offr);/*得到可读字符个数*/

for(rstart=0;rstart

{

*ca=*(pipecb3575[pf].p_addr+offr%PSIZE);

ca++;

offr++;

}

file[r].f_offset=offr;/*重定位读指针位置*/

printf("weakthewritethread,makethepipewritable\n");

pthread_cond_signal(&wflag);

printf("----releasethelock\n");

pthread_mutex_unlock(&lock);

printf("Secceed(pipe---->memory)outputdatafromthepipeintomemory*ca\n");

returnm;

}

/*线程调用,读源文件,写管道*/

void*pwrite3575(void*a)//将源文件a内容写入管道中

{

printf("(file---->pipe)inputdatafromtheoriginalfileintopipe\n");

charabuf1[BSIZE];

structarg_set*args=(structarg_set*)a;/*需要传入多个参数时,用结构体传*/

intfdr;

intn_r;/*管道文件写入字符数*/

if((fdr=open(args->fname,O_RDONLY))!

=-1)

{

while((n_r=read(fdr,abuf1,BSIZE))>0)/*读文件,写管道*/

{

printf("(file---->memory)inputdatainoriginalfileintomemory*ca\n");

printf("Secceed(file---->memory)inputdatainoriginalfileintomemory*ca\n");

//printf("(memory---->pipe)inputdatainmemory*caintopipe\n");

write_simulate3575(args->f,abuf1,n_r);

//printf("Secceed(memory---->pipe)input\n");

}

pipecb3575[file[u_ofile3575[args->f]].f_inode].p_count--;/*文件已读完,关闭管道写端*/

}

else

{

perror(args->fname);/*打开源文件可能不成功*/

returnNULL;

}

printf("Secceed(file---->pipe)inputdatafromtheoriginalfileintopipe\n");

returnNULL;

}

/*线程调用,写目标文件,读管道*/

void*pread3575(void*a)//读取管道,将其中内容写入新建文件中

{

printf("(pipe---->file)outputdatafromthepipeintonewfile\n");

charabuf2[BSIZE];/*缓冲区*/

structarg_set*args=(structarg_set*)a;/*需要传入多个参数时,用结构体传*/

intfdw;

intn_w;/*管道文件读出字符数*/

if((fdw=open(args->fname,O_CREAT|O_RDWR,0777))!

=-1)

{

while((n_w=read_simulate3575(args->f,abuf2,BSIZE))>0)/*读管道,写文件*/

{

//printf("(pipe---->memory)outputdatafrompipeintomemory*ca\n");

//printf("Secceed(pipe---->memory)outputdatafrompipeintomemory*ca\n");

printf("(memory---->file)outputdatainmemory*caintofile\n");

write(fdw,abuf2,n_w);

printf("Secceed(memory---->file)outputdatafromthepipeintonewfile\n");

}

}

else

{

perror(args->fname);/*打开目标文件可能出错*/

returnNULL;

}

printf("Secceed(pipe---->file)outputdatafromthepipeintonewfile\n");

returnNULL;

}

/*主函数*/

intmain(intargc,char*argv[])

{

intx;

u_ofile_init3575();

while((x=pipe_simulate3575(fd))==-1);/*创建管道,即申请空间*/

if(x==-2)

return-1;

pthread_tt;//threadID

structarg_setargs[2];/*用结构体传写线程需要的参数:

文件名,管道文件读写端*/

args[0].fname=argv[1];/*源文件名*/

args[0].f=fd[1];/*管道文件写端*/

args[1].fname=argv[2];/*目标文件名*/

args[1].f=fd[0];/*管道文件读端*/

pthread_create(&t,NULL,pwrite3575,(void*)&args[0]);/*创建子线程,写管道*/

pread3575((void*)&args[1]);/*主线程调用,读管道*/

pthread_join(t,NULL);/*等待写线程结束*/

close_simulate3575(fd);

printf("\nnumofread_simulate3575=%d\n",numread_simulate3575);

printf("numofwrite_simulate3575=%d\n",numwrite_simulate3575);

return0;

}

附录二(实验结果):

ls-l

总用量2379

-rw-r--r--1johnjohn502012-12-1718:

063575

-rw-r--r--1johnjohn368642012-07-1507:

533575.doc

-rw-r--r--1johnjohn954412012-08-2722:

163575.JPG

-rw-r--r--1johnjohn20839692010-11-0813:

073575.mp3

-rw-r--r--1johnjohn848352012-07-1113:

223575.pdf

-rw-r--r--1johnjohn737282012-12-1716:

483575.ppt

-rw-r--r--1johnjohn199242012-07-0318:

513575.rar

-rw-r

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

当前位置:首页 > 工程科技 > 材料科学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1