线程(进程)并发拷贝程序程序代码软件一班#includestdio.h#includesys/types.h#includesys/stat.h#includefcntl.h#includeunistd.h#includepthread.h#includemalloc.h#definePSIZE4096/*管道文件的大小*/#defineBSIZE128/*默认缓冲区的大小*/#defineNOFILE20/*u_ofile1013表可分配的个数*/#defineNFILE20/*file表可分配的个数*/#defineNPIPE20/*pipecb1013可分配的个数*//*进程的u_file表*/intu_ofile1013[NOFILE];/*模拟file表*/struct{charf_flag;/*读写标志,'w'表示写,'r'表示读*/intf_count;/*表示此表项的状态,=0表示此表项没被使用,可分配;=1表示此表项在被使用,不可再分配*/intf_inode;/*对应的pipecb1013表下标*/longf_offset;/*读写指针,当前已读或已写个数*/}file[NFILE];/*管道控制块*/struct{char*p_addr;/*管道文件基地址*/intp_size;/*管道文件大小,PSIZE*/intp_count;/*=2表示读写都在被进行,=1表示在被读或被写,=0表示管道没被使用,可分配*/}pipecb1013[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_ofile1013表初始化*/intu_ofile_init1013(){printf(输入文件u_ofile1013\n);inti;for(i=0;iNOFILE;i++)u_ofile1013[i]=-1;u_ofile1013[0]=0;u_ofile1013[1]=0;u_ofile1013[2]=0;return0;}/*创建管道*/intpipe_simulate1013(inta[]){printf(开始创建一个管道\n);inti;for(i=0;iNOFILE;i++){if(u_ofile1013[i]==-1){a[0]=i;/*读*/u_ofile1013[i]=0;/*读端*/break;}}for(i;iNOFILE;i++){if(u_ofile1013[i]==-1){a[1]=i;/*写*/u_ofile1013[i]=1;/*写端*/break;}}if(i=NOFILE){printf(u_ofile1013分配失败,创建管道失败!\n);return-2;}pfile=(char*)malloc(PSIZE*sizeof(char));/*申请模拟管道用的内存空间*/if(pfile==NULL)/*申请可能不成功*/{printf(创建管道失败\n);return-1;}for(i=0;iNFILE;i++){if(file[i].f_count!=1){file[i].f_flag='r';/*读标志*//*file[i].f_inode=0;读对应pipecb1013表下标*/file[i].f_count=1;/*file[0]这个表项在被使用,不可再分配*/file[i].f_offset=0;/*读指针*/u_ofile1013[a[0]]=i;/*读端*/break;}}for(i=0;iNFILE;i++){if(file[i].f_count!=1){file[i].f_flag='w';/*写标志*//*file[i].f_inode=0;写对应pipecb1013控制块下标*/file[i].f_count=1;/*file[1]这个表项在被使用,不可再分配*/file[i].f_offset=0;/*写指针*/u_ofile1013[a[1]]=i;/*写端*/break;}}if(i=NFILE){printf(创建管道失败\n);return-1;}for(i=0;iNPIPE;i++){if(pipecb1013[i].p_count==0){pipecb1013[i].p_addr=pfile;/*给管道文件基地址赋值*/pipecb1013[i].p_size=PSIZE;/*管道文件大小*/pipecb1013[i].p_count=2;/*读写都在进行,此pipecb1013表项不可再分*/file[u_ofile1013[a[0]]].f_inode=i;file[u_ofile1013[a[1]]].f_inode=i;break;}}if(i=NPIPE){printf(----创建管道失败\n);return-1;}printf(创建管道成功\n);return0;/*分配成功*/}/*关闭管道*/intclose_simulate1013(inta[]){printf(----开始关闭管道\n);char*p;inti;for(i=0;i2;i++){p=pipecb1013[file[u_ofile1013[a[i]]].f_inode].p_addr;/*if(p!=NULL)free(p);//释放管道内存*/pipecb1013[file[u_ofile1013[a[i]]].f_inode].p_count=0;/*管道控制块计数清零*/file[u_ofile1013[a[i]]].f_count=0;/*file表项计数清零*/u_ofile1013[a[i]]=-1;/*u_ofile1013表项清空*/a[i]=-1;/*fdp[]清空?*/}printf(关闭管道成功\n);return0;}/*写管道*/intnumwrite_simulate1013;intwrite_simulate1013(intfd,char*ca,intn)//将内存ca内容写入n个字符到管道fd里{printf(将内存内容写入n个字符到管道里\n);numwrite_simulate1013++;longoffr,offw;/*读写指针,实际是读写字符个数*/intr;/*管道文件读端*/intm;/*若ca中的字符不能一次写完,m用来表示一次可写入的字符的最大数*/intw=u_ofile1013[fd];/*管道文件写端*/intpf=file[w].f_inode;/*读管道对应的pipecb1013表的下标*/intn1=n;/*一次应该写入的字符个数*/intwstart=0;/*计数器,写入字符个数*/inti=0;for(i;iNFILE;i++)/*寻找写管道对应的读管道的读端*/{if((file[i].f_flag=='r')&&(file[i].f_inode==pf)){r=i;break;}else{continue;}}printf(加锁\n);pthread_mutex_lock(&lock);/*互斥锁,相当于进入临界区*/offr=file[r].f_offset;/*赋值读指针*/offw=file[w].f_offset;/*赋值写指针*/if((offw+n1-PSIZE)offr)/*不能一次写完*/{if(pipecb1013[pf].p_count==0)/*对文件的复制操作已进行结束,管道文件被释放*/{printf(----对文件的复制操作已进行结束,管道文件被释放\n);return0;}else{m=PSIZE+offr-offw;/*最多可写入数*/for(wstart=0;wstartm;wstart++){*(pipecb1013[pf].p_addr+offw%PSIZE)=*ca;ca++;offw++;}file[w].f_offset=offw;/*重定位写指针位置*/n1=n1-m;/*剩余需要读的字符个数*/printf(----唤醒读进程,管道可读\n);pthread_cond_signal(&rflag);/*唤醒读线程,管道可读*/printf(写线程被阻塞和等待声明\n);pthread_cond_wait(&wflag,&lock);/*写线程封锁等待*/}}/*一次性可将ca中内容全部写入管道*/offr=file[r].f_offset;offw=file[w].f_offset;for(wstart=0;wstartn1;wstart++){/*printf(%d\n,pipecb1013[pf].p_addr);*/*(pipecb1013[pf].p_addr+offw%PSIZE)=*ca;/*printf(%d\n,wstart);*/ca++;offw++;}file[w].f_offset=offw;pthread_cond_signal(&rflag);printf(释放锁\n);pthread_mutex_unlock(&lock);printf(成功将ca中内容全部写入管道\n);returnn;/*返回写入字符个数*/}/*读管道*/intnumread_simulate1013;//read_simulate1013diaoyongshuintread_simulate1013(intfd,char*ca,intn)//将管道fd内容读取n个字符到内存ca里{printf(----将管道fd内容读取n个字符到内存ca里\n);numread_simulate1013++;longoffr,offw;/*读写指针,实际是读写字符个数*/intw;/*管道文件写端*/intm;/*若ca中的字符不能一次读完,m用来表示一次可读出的字符的最大数*/intr=u_ofile1013[fd];/*管道文件读端*/intpf=file[r].f_inode;/*读管道对应的pipecb1013表的下标*/intrstart=0;/*计数器,读出字符个数*/inti=0;for(i;iNFILE;i++)/*寻找读管道对应的读管道的端*/{if((file[i].f_flag=='w')&&(file[i].f_inode==pf)){w=i;break;}else{continue;}}printf(----加锁\n);pthread_mutex_lock(&lock);/*互斥锁,相当于进入临界区*/offr=file[r].f_offset;/*赋值读指针*/offw=file[w].f_offset;/*赋值写指针*/if(offr==offw)/*管道空,无内容可读*/{printf(----管道为空,无内容可读\n);if(pipecb1013[pf].p_count==1)/*写端关闭*/{pipecb1013[pf].p_count--;/*文件的复制以完成,释放管道文件的空间*/printf(----写端关闭,文件复制完成\n);return0;}else{printf(----唤醒写线程,管道可写\n);pthread_cond_signal(&wflag);/*唤醒写线程,管道可写*/printf(----读线程封锁等待\n);pthread_cond_wait(&rflag,&loc