《线程并发拷贝程序实验报告及实验结果(共8页).doc》由会员分享,可在线阅读,更多相关《线程并发拷贝程序实验报告及实验结果(共8页).doc(8页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、精选优质文档-倾情为你奉上附录一 程序代码#include#include#include#include#include#include#define PSIZE 4096 /*管道文件的大小*/#define BSIZE 128 /*默认缓冲区的大小*/#define NOFILE 20 /*u_ofile表可分配的个数*/#define NFILE 20 /*p_file表可分配的个数*/#define NPIPE 20 /*p_fcb可分配的个数*/*进程的u_file表*/int u_ofileNOFILE;/*模拟file表*/struct char f_flag;/*读写标志,w
2、表示写,r表示读*/ int f_count;/*表示此表项的状态,=0表示此表项没被使用,可分配;=1表示此表项在被使用,不可再分配*/ int f_inode;/*对应的p_fcb表下标*/ long f_offset;/*读写指针,当前已读或已写个数*/p_fileNFILE;/*管道控制块*/struct char *p_addr;/*管道文件基地址*/ int p_size;/*管道文件大小,PSIZE*/ int p_count;/*=2表示读写都在被进行,=1表示在被读或被写,=0表示管道没被使用,可分配*/p_fcbNPIPE;/*模拟管道文件*/char *pfile;/*管
3、道的写入写出端*/int fd2;/*锁机制,实现互斥*/pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;/*进程间通信,实现同步*/pthread_cond_t rflag = PTHREAD_COND_INITIALIZER;/*读信号量*/pthread_cond_t wflag = PTHREAD_COND_INITIALIZER;/*写信号量*/*线程创建函数只能传一个参数,用结构体来封装所有参数*/struct arg_set char *fname; /*文件名*/ int f; /*传递fdp*/;/*u_ofile表初始化*/
4、int u_ofile_init() int i; for(i=0;iNOFILE;i+) u_ofilei = -1; u_ofile0=0; u_ofile1=0; u_ofile2=0; return 0;/*创建管道*/int ppipe(int a) int i; for(i=0;iNOFILE;i+) if(u_ofilei=-1) a0 = i;/*读*/ u_ofilei = 0;/*读端*/ break; for(i;i=NOFILE) printf(u_ofile分配失败n); return -2; pfile = (char *)malloc(PSIZE*sizeof(c
5、har);/*申请模拟管道用的内存空间*/ if(pfile=NULL)/*申请可能不成功*/ return -1; for(i=0;iNFILE;i+) if(p_filei.f_count!=1) p_filei.f_flag = r;/*读标志*/ /p_filei.f_inode = 0;/*读对应p_fcb表下标*/ p_filei.f_count = 1;/*p_file0这个表项在被使用,不可再分配*/ p_filei.f_offset = 0;/*读指针*/ u_ofilea0 = i;/*读端*/ break; for(i=0;i=NFILE) return -1; for(
6、i=0;i=NPIPE) return -1; return 0;/*分配成功*/*关闭管道*/int p_close(int a) char *p; int i; for(i=0;i2;i+) p=p_fcbp_fileu_ofileai.f_inode.p_addr; if(p!=NULL) free(p); /*释放管道内存*/ p_fcbp_fileu_ofileai.f_inode.p_count = 0; /*管道控制块计数清零*/ p_fileu_ofileai.f_count = 0; /*file表项计数清零*/ u_ofileai = -1; /*u_ofile表项清空*/
7、 ai = -1; /*fdp清空?/ return 0;/*写管道*/int writep(int fd,char *ca,int n) long offr,offw;/*读写指针,实际是读写字符个数*/ int r;/*管道文件读端*/ int m;/*若ca中的字符不能一次写完,m用来表示一次可写入的字符的最大数*/ int w = u_ofilefd;/*管道文件写端*/ int pf = p_filew.f_inode;/*读管道对应的p_fcb表的下标*/ int n1 = n;/*一次应该写入的字符个数*/ int wstart = 0;/*计数器,写入字符个数*/ int i
8、= 0 for(i;ioffr)/*不能一次写完*/ if(p_fcbpf.p_count=0)/*对文件的复制操作已进行结束,管道文件被释放*/ return 0; else m = PSIZE+offr-offw;/*最多可写入数*/ for(wstart=0;wstartm;wstart+) *(p_fcbpf.p_addr+offw%PSIZE) = *ca; ca+; offw+; p_filew.f_offset = offw;/*重定位写指针位置*/ n1 = n1-m;/*剩余需要读的字符个数*/ pthread_cond_signal(&rflag);/*唤醒读线程,管道可读
9、*/ pthread_cond_wait(&wflag,&lock);/*写线程封锁等待*/ /*一次性可将ca中内容全部写入管道*/ offr = p_filer.f_offset; offw = p_filew.f_offset; for(wstart=0;wstartn1;wstart+) /*printf(%dn,p_fcbpf.p_addr);*/ *(p_fcbpf.p_addr+offw%PSIZE) = *ca; /*printf(%dn,wstart);*/ ca+; offw+; p_filew.f_offset = offw; pthread_cond_signal(&r
10、flag); pthread_mutex_unlock(&lock); return n;/*返回写入字符个数*/*读管道*/int readp(int fd,char *ca,int n) long offr,offw;/*读写指针,实际是读写字符个数*/ int w;/*管道文件写端*/ int m;/*若ca中的字符不能一次读完,m用来表示一次可读出的字符的最大数*/ int r = u_ofilefd;/*管道文件读端*/ int pf = p_filer.f_inode;/*读管道对应的p_fcb表的下标*/ int rstart = 0;/*计数器,读出字符个数*/ int i =
11、 0; for(i;iNFILE;i+)/*寻找读管道对应的读管道的端*/ if(p_filei.f_flag=w)&(p_filei.f_inode=pf) w = i; break; else continue; pthread_mutex_lock(&lock);/*互斥锁,相当于进入临界区*/ offr = p_filer.f_offset;/*赋值读指针*/ offw = p_filew.f_offset;/*赋值写指针*/ if(offr=offw)/*管道空,无内容可读*/ if(p_fcbpf.p_count=1)/*写端关闭*/ p_fcbpf.p_count-;/*文件的复
12、制以完成,释放管道文件的空间*/ return 0; else pthread_cond_signal(&wflag);/*唤醒写线程,管道可写*/ pthread_cond_wait(&rflag,&lock);/*写线程封锁等待*/ offr = p_filer.f_offset; offw = p_filew.f_offset; m = n=(offw-offr)?n:(offw-offr);/*得到可读字符个数*/ for(rstart=0;rstartfname,O_RDONLY)!=-1) while(n_r=read(fdr,abuf1,BSIZE)0)/*读文件,写管道*/ w
13、ritep(args-f,abuf1,n_r); p_fcbp_fileu_ofileargs-f.f_inode.p_count-;/*文件已读完,关闭管道写端*/ else perror(args-fname);/*打开源文件可能不成功*/ return NULL;/*线程调用,写目标文件,读管道*/void *pread(void *a) char abuf2BSIZE;/*缓冲区*/ struct arg_set *args=(struct arg_set *)a;/*需要传入多个参数时,用结构体传*/ int fdw; int n_w;/*管道文件读出字符数*/ if(fdw=ope
14、n(args-fname,O_CREAT|O_RDWR,0777)!=-1) while(n_w=readp(args-f,abuf2,BSIZE)0)/*读管道,写文件*/ write(fdw,abuf2,n_w); else perror(args-fname);/*打开目标文件可能出错*/ return NULL;/*主函数*/int main(int argc,char *argv) int x; u_ofile_init(); while(x=ppipe(fd)=-1);/*创建管道,即申请空间*/ if(x=-2) return -1; pthread_t t; struct ar
15、g_set args2;/*用结构体传写线程需要的参数:文件名,管道文件读写端*/ args0.fname=argv1;/*源文件名*/ args0.f=fd1;/*管道文件写端*/ args1.fname=argv2;/*目标文件名*/ args1.f=fd0;/*管道文件读端*/ pthread_create(&t,NULL,pwrite,(void *)&args0);/*创建子线程,写管道*/ pread(void *)&args1);/*主线程调用,读管道*/ pthread_join(t,NULL);/*等待写线程结束*/ p_close(fd); return 0;附录二 实验结果1. 小型文本文件测试:2 中型文本文件测试:3 大型文本文件测试:4 生成的目标文件与源文件的比较:专心-专注-专业