线程并发拷贝程序实验报告及实验结果

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

1/8附录一程序代码#includestdio.h#includesys/types.h#includesys/stat.h#includefcntl.h#includeunistd.h#includepthread.h#definePSIZE4096/*管道文件的大小*/#defineBSIZE128/*默认缓冲区的大小*/#defineNOFILE20/*u_ofile表可分配的个数*/#defineNFILE20/*p_file表可分配的个数*/#defineNPIPE20/*p_fcb可分配的个数*//*进程的u_file表*/intu_ofile[NOFILE];/*模拟file表*/struct{charf_flag;/*读写标志,'w'表示写,'r'表示读*/intf_count;/*表示此表项的状态,=0表示此表项没被使用,可分配;=1表示此表项在被使用,不可再分配*/intf_inode;/*对应的p_fcb表下标*/longf_offset;/*读写指针,当前已读或已写个数*/}p_file[NFILE];/*管道控制块*/struct{char*p_addr;/*管道文件基地址*/intp_size;/*管道文件大小,PSIZE*/intp_count;/*=2表示读写都在被进行,=1表示在被读或被写,=0表示管道没被使用,可分配*/}p_fcb[NPIPE];/*模拟管道文件*/char*pfile;/*管道的写入写出端*/intfd[2];/*锁机制,实现互斥*/pthread_mutex_tlock=PTHREAD_MUTEX_INITIALIZER;/*进程间通信,实现同步*/pthread_cond_trflag=PTHREAD_COND_INITIALIZER;/*读信号量*/pthread_cond_twflag=PTHREAD_COND_INITIALIZER;/*写信号量*//*线程创建函数只能传一个参数,用结构体来封装所有参数*/2/8structarg_set{char*fname;/*文件名*/intf;/*传递fdp[]*/};/*u_ofile表初始化*/intu_ofile_init(){inti;for(i=0;iNOFILE;i++)u_ofile[i]=-1;u_ofile[0]=0;u_ofile[1]=0;u_ofile[2]=0;return0;}/*创建管道*/intppipe(inta[]){inti;for(i=0;iNOFILE;i++){if(u_ofile[i]==-1){a[0]=i;/*读*/u_ofile[i]=0;/*读端*/break;}}for(i;iNOFILE;i++){if(u_ofile[i]==-1){a[1]=i;/*写*/u_ofile[i]=1;/*写端*/break;}}if(i=NOFILE){printf(u_ofile分配失败\n);return-2;}pfile=(char*)malloc(PSIZE*sizeof(char));/*申请模拟管道用的内存空间*/3/8if(pfile==NULL)/*申请可能不成功*/{return-1;}for(i=0;iNFILE;i++){if(p_file[i].f_count!=1){p_file[i].f_flag='r';/*读标志*///p_file[i].f_inode=0;/*读对应p_fcb表下标*/p_file[i].f_count=1;/*p_file[0]这个表项在被使用,不可再分配*/p_file[i].f_offset=0;/*读指针*/u_ofile[a[0]]=i;/*读端*/break;}}for(i=0;iNFILE;i++){if(p_file[i].f_count!=1){p_file[i].f_flag='w';/*写标志*///p_file[i].f_inode=0;/*写对应p_fcb控制块下标*/p_file[i].f_count=1;/*p_file[1]这个表项在被使用,不可再分配*/p_file[i].f_offset=0;/*写指针*/u_ofile[a[1]]=i/*写端*/break;}}if(i=NFILE){return-1;}for(i=0;iNPIPE;i++){if(p_fcb[i].p_count==0){p_fcb[i].p_addr=pfile;/*给管道文件基地址赋值*/p_fcb[i].p_size=PSIZE;/*管道文件大小*/p_fcb[i].p_count=2;/*读写都在进行,此p_fcb表项不可再分*/p_file[u_ofile[a[0]]].f_inode=i;p_file[u_ofile[a[1]]].f_inode=i;break;}}4/8if(i=NPIPE){return-1;}return0;/*分配成功*/}/*关闭管道*//intp_close(inta[]){char*p;inti;for(i=0;i2;i++){p=p_fcb[p_file[u_ofile[a[i]]].f_inode].p_addr;if(p!=NULL)free(p);/*释放管道内存*/p_fcb[p_file[u_ofile[a[i]]].f_inode].p_count=0;/*管道控制块计数清零*/p_file[u_ofile[a[i]]].f_count=0;/*file表项计数清零*/u_ofile[a[i]]=-1;/*u_ofile表项清空*/a[i]=-1;/*fdp[]清空?/}return0;}/*写管道*/intwritep(intfd,char*ca,intn){longoffr,offw;/*读写指针,实际是读写字符个数*/intr;/*管道文件读端*/intm;/*若ca中的字符不能一次写完,m用来表示一次可写入的字符的最大数*/intw=u_ofile[fd];/*管道文件写端*/intpf=p_file[w].f_inode;/*读管道对应的p_fcb表的下标*/intn1=n;/*一次应该写入的字符个数*/intwstart=0;/*计数器,写入字符个数*/inti=0for(i;iNFILE;i++)/*寻找写管道对应的读管道的读端*/{if((p_file[i].f_flag=='r')&&(p_file[i].f_inode==pf)){r=i;break;}else{continue;5/8}}pthread_mutex_lock(&lock);/*互斥锁,相当于进入临界区*/offr=p_file[r].f_offset;/*赋值读指针*/offw=p_file[w].f_offset;/*赋值写指针*/if((offw+n1-PSIZE)offr)/*不能一次写完*/{if(p_fcb[pf].p_count==0)/*对文件的复制操作已进行结束,管道文件被释放*/{return0;}else{m=PSIZE+offr-offw;/*最多可写入数*/for(wstart=0;wstartm;wstart++){*(p_fcb[pf].p_addr+offw%PSIZE)=*ca;ca++;offw++;}p_file[w].f_offset=offw;/*重定位写指针位置*/n1=n1-m;/*剩余需要读的字符个数*/pthread_cond_signal(&rflag);/*唤醒读线程,管道可读*/pthread_cond_wait(&wflag,&lock);/*写线程封锁等待*/}}/*一次性可将ca中内容全部写入管道*/offr=p_file[r].f_offset;offw=p_file[w].f_offset;for(wstart=0;wstartn1;wstart++){/*printf(%d\n,p_fcb[pf].p_addr);*/*(p_fcb[pf].p_addr+offw%PSIZE)=*ca;/*printf(%d\n,wstart);*/ca++;offw++;}p_file[w].f_offset=offw;pthread_cond_signal(&rflag);pthread_mutex_unlock(&lock);returnn;/*返回写入字符个数*/}/*读管道*/intreadp(intfd,char*ca,intn)6/8{longoffr,offw;/*读写指针,实际是读写字符个数*/intw;/*管道文件写端*/intm;/*若ca中的字符不能一次读完,m用来表示一次可读出的字符的最大数*/intr=u_ofile[fd];/*管道文件读端*/intpf=p_file[r].f_inode;/*读管道对应的p_fcb表的下标*/intrstart=0;/*计数器,读出字符个数*/inti=0;for(i;iNFILE;i++)/*寻找读管道对应的读管道的端*/{if((p_file[i].f_flag=='w')&&(p_file[i].f_inode==pf)){w=i;break;}else{continue;}}pthread_mutex_lock(&lock);/*互斥锁,相当于进入临界区*/offr=p_file[r].f_offset;/*赋值读指针*/offw=p_file[w].f_offset;/*赋值写指针*/if(offr==offw)/*管道空,无内容可读*/{if(p_fcb[pf].p_count==1)/*写端关闭*/{p_fcb[pf].p_count--;/*文件的复制以完成,释放管道文件的空间*/return0;}else{pthread_cond_signal(&wflag);/*唤醒写线程,管道可写*/pthread_cond_wait(&rflag,&lock);/*写线程封锁等待*/}}offr=p_file[r].f_offset;offw=p_file[w].f_offset;m=n=(offw-offr)?n:(offw-offr);/*得到可读字符个数*/for(rstart=0;rstartm;rstart++){*ca=*(p_fcb[pf].p_addr+offr%PSIZE);ca++;7/8offr++;}p_file[r].f_offset=offr;/*重定位读指针位置*/pthread_cond_signal(&wflag);pthread_mutex_unlock(&lock);returnm;}/*线程调用,读源文件,写管道*/void*pwrite(void*a){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)/*读文件,写管道*/writep(args-f,abuf1,n_r);p_fcb[p_file[u_ofile[args-f]].f_inode].p_count--;/*文件已读完,关闭管道写端*/}else{perror(args-fname);/*打开源文件可能不成功*/}returnNULL;}/*线程调用,写目标文件,读管道*/void*pread(void*a){charabuf2[BSIZE];/*缓冲区*/structarg_set*args=(structarg_set*)a;/*需要传入多个参数时,用结构体传*/intfdw;intn_w;/*管道文件读出字符数*/if((fdw=open(args-fname,O

1 / 8
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功