1.子プロセスのコピー前半、子プロセスまで親プロセスブロックし、その後終了コピーコピー後の前半
/ * 前半の内容をコピーするために子プロセスを待ってブロックするために、親プロセスがファイルの最初の半分をコピーするための子プロセスは、終了 *その後、半分の内容の後に、親プロセスをコピー * * / の#include <stdio.hに> する#include <stdlib.h>に含ま 書式#include <unistd.h> 書式#include <SYS / types.h>に する#include <SYS / STATの.h> の#include <fcntl.h> の#include <SYS / 待機の.h> // ;フォーク(無効)pid_t int型メイン(int型 ARGC、CONST のchar * ARGV []) { int型fd_r、fd_w; チャー BUFの[ 5 ] = { 0 }; INT ステータス; fd_r =オープン(のargv [ 1。、O_RDONLYの]); //は内容読み取るためにファイルを開く IF(fd_r < 0 ) {perrorは(" ファイルを開く失敗を読み取り:");リターン- 1 ;} fd_w =オープン(ARGV [ 2 ]、O_WRONLY | O_APPEND、0666); //は、書き込みのためのファイルを開く IF(fd_w < 0 ) {perrorは(" ファイルオープン失敗を記述します");閉じる(fd_r);リターン- 1 ;} off_tではFILESIZEの = 0 ; //ファイルサイズ ファイルサイズ=のlseek(fd_r、0、SEEK_END) -のlseek(fd_r、0、SEEK_SET); // ソースファイルを読み込むには、文字の数を持っている:W のprintf(" ソースファイルサイズ:%LDの\のN- " 、ファイルサイズ)。 off_t型のc_read_size; // 子プロセスは、ファイルサイズ読み出し c_read_size =ファイルサイズ/ 2 ; ; off_tではf_read_sizeの// 、親プロセスファイルサイズ読み出し f_read_size =ファイルサイズ- c_read_sizeと、 の#if 1 pid_t PID、 PIDは = (フォーク)。 IF(PID == - 1){perrorは(" PID失敗:");出口(1 );} そう IF(PIDの== 0)// 子プロセス { printf関数は(" 子プロセスが開始\ N- " ); のprintf(" 子プロセスが読み込みサイズ:%LDの\のN- " 、c_read_size); ssize_tのsize_cnt = 0 ; // 読み取りの数を記録 = ssize_tのtemp_size 0 ; // 一時的読み取り可能な記録 しばらく(1)// サイクルタイムを読み取る中間位置に { temp_sizeを(fd_r、BUF、読み取り= 1。); IF(temp_size < =0)// データを読み込む、またはエラー読み取ることがない { のprintf(" 子エンド読むか、失敗\ N- " ); BREAKを; } ssize_tのをTT = 0 ; // 子プロセスの書き込み失敗 TT = 書き込み(fd_w、BUF 、1); // ファイルに書き込まれたデータ読み取り IF(TTは== - 1 ) {perrorは(" 子失敗書き込みファイル:" ); BREAK;} size_cnt = size_cnt + temp_size; IF(size_cnt> = c_read_size)// 読み出したデータを読み込む { のprintf(" 子ファイル書き込み終了の\ N- " ); BREAK; } } 終了(1。); // 終了サブプロセス } 他 // 親 { のwaitpid (PID、 &ステータス、0); // のインプリメンテーションの実行に子供を待つ のprintf(" N- \親プロセスの開始を" ); のprintfは(" 親プロセスのサイズを読み込む:N- \%のLD " 、f_read_sizeを); のlseek(fd_r、-f_read_size、SEEK_END); // ファイルの末尾からの相対が読み取ること子の位置に移動させ 、一方を(1)// 読み取りを開始 { ssize_tのf_read_sizeと、 f_read_size =読む(fd_r、BUF、。1 )、 IF(f_read_size < = 0)// 戻り値の終わりに読み出さ0 { のprintf(" 父親がファイル終了の\ N-を読み取る" ); BREAK; } ssize_tのT = 0 ; // 親プロセスは、書き込みに失敗した T = ライト(fd_w、BUFを1 ); もしさ(t == - 1 ) { perrorは(" 父の書き込みファイルが失敗:" ); ブレーク; } } のprintf(" 父書き込みファイルの末尾の\ nを" ); 出口(1 )。 } #endifの 近く(fd_r)。 クローズ(fd_w)。 リターン0 ; }
テスト:
2.同時に親と子のコピーは、親プロセス、子プロセスのコピーの前半の後に不確実性のシーケンシャル書き込みファイルコピーの半分なので、書かれた内容は、混乱になります
/* copy文件,父进程先拷贝前一半,子进程拷贝后一半 * 文件内容可以完整拷贝,写数据时顺序会打乱 * 父进程写一点,子进程写一点 * */ #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/wait.h> int main(int argc, const char *argv[]) { int fd_r,fd_w; off_t size; char ch = '\0'; pid_t pid; char buf[64] = {0}; ssize_t tmp = 0; if((fd_r = open(argv[1],O_RDONLY)) == -1) { perror("fcntlail to open fd_r"); exit(1); } if((fd_w = open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0666)) == -1) //打开写的文件,没有就创建,有内容就清空,只写方式打开 { close(fd_r); perror("fail to open FD_ZEROBASED_w"); exit(1); } size = lseek(fd_r,0,SEEK_END); lseek(fd_w,size - 1,SEEK_SET); write(fd_w,&ch,1);//在文件的末尾先添加一个 '\0' 结尾符,确定写文件的大小 size /= 2; //size = size / 2; //文件大小的一半 pid = fork(); if(pid < 0) { perror("fail to fork"); exit(1); } else if(pid == 0) //子进程拷贝后一半 { lseek(fd_r,size,SEEK_SET); lseek(fd_w,size,SEEK_SET); while((tmp = read(fd_r,buf,sizeof(buf))) > 0) { write(fd_w,buf,tmp); } close(fd_r); close(fd_w); exit(0); } else //父进程,拷贝前一半 { lseek(fd_r,0,SEEK_SET); lseek(fd_w,0,SEEK_SET); while(1) { if(size > sizeof(buf)) { tmp = read(fd_r,buf,sizeof(buf)); } else { tmp = read(fd_r,buf,size); } if(tmp <= 0) { break; } size -= tmp;//size = size - tmpfd_w; write(fd_w,buf,tmp); } wait(NULL);//等待回收子进程 close(fd_r); close(fd_w); } return 0; }