色yeye在线视频观看_亚洲人亚洲精品成人网站_一级毛片免费播放_91精品一区二区中文字幕_一区二区三区日本视频_成人性生交大免费看

Hi,歡迎來到嵌入式培訓高端品牌 - 華清遠見教育科技集團<北京總部官網>,專注嵌入式工程師培養15年!
當前位置: > 華清遠見教育科技集團 > 嵌入式學習 > 講師博文 > 如何實現多進程寫一個文件
如何實現多進程寫一個文件
時間:2017-01-05作者:華清遠見

如何利用多進程,來實現文件的拷貝?

在我們學習IO的時候,曾經利用文件IO函數,標準IO函數都實現了對文件的拷貝,那么在我們學習過進程間通信后,就可以創建多個進程來完成對同一個文件的讀寫。例如讓父進程寫文件的前半部分,子進程來寫文件的后半部分,因為兩個進程間是可以并發執行的,所以將會節約一部分時間,提高執行的效率。那么怎樣才能實現這個功能?

我們以文件IO為例,邊講述如何實現的同時,也給大家說下為什么這樣寫的原因,希望能給大家得到些啟發。

首先來看下用文件IO函數實現拷貝文件的程序:

#include <sys/types.h>
        #include <sys/stat.h>
        #include <fcntl.h>
        #include <stdio.h>
        #define maxsize 256 
        int main(int argc,char *argv[])
        {
                if(argc!=3)                //如果命令格式不正確
                { 
                        printf("command error!\n");
                        return -1;
                }

        int fd1,fd2;
                if ((fd1= open(argv[1],O_RDONLY))< 0)
                {
                        perror("error");
                        return -1;
                }
                if ((fd2 = open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0644))< 0)
                {
                        perror("error");
                        return -1;
                }
                char s[maxsize ];
                int t=0;
                while ((t=read(fd1,s,maxsize ))==maxsize )
                {
                        write(fd2,s,t);
                }
                write(fd2,s,t);
                close(fd1);
                close(fd2);
                return 0;
        }

這樣就實現了文件的拷貝。那么在我們學習完fork函數之后是不是只要父進程和子進程分別寫一部分就可以了?

if((src=open(argv[1],O_RDONLY))<0)
        {
                ……
        }
        if((des=open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0644))<0)
        {
                ……
        }
        len=lseek(src,0,SEEK_END);
        int pid;
        if((pid=fork())<0)
        {
                fprintf(stderr,"fork error!:%s\n",strerror(errno));
                return -1;
        }
        else if(pid ==0)
        {
                lseek(src,len/2,SEEK_SET);
                lseek(des,len/2,SEEK_SET);
                while((n=read(src,buf,sizeof(buf)))!=0)
                {
                        write(des,buf,n);
                }
                exit(0); 
        }
        else
        {
                lseek(src,0,SEEK_SET);
                lseek(des,0,SEEK_SET);
                while((n=read(src,buf,sizeof(buf)))!=0) 
                {
                        write(des,buf,n);
                        if(lseek(src,0,SEEK_CUR) > len/2)
                        break;
                }
                wait(NULL);
                exit(0);
        }

是不是只要這樣寫就可以實現功能?實踐證明這樣寫不行的,那么為什么這樣寫不可以呢?

子進程和父進程繼續執行fork之后的指令。子進程是父進程的復制品。子進程獲得父進程數據空間、堆棧的復制品。注意,這是子進程所擁有的拷貝,父、子進程并不共享這些存儲空間部分。那么跟本例相關的一條fork特性就是由父進程打開的文件描述符也被復制到子程序中。父、子進程的每個相同的打開描述符共享一個文件表項。

在unix高級環境編程中有這樣一幅圖

這種共享文件的方式使父、子進程對同一個文件使用了一個文件位移量。當父進程是其標準輸出重新定向,那么子進程寫到該標準輸出時,它將更新與父進程共享的該文件的位移量。當程序中,父、子進程寫到同一個描述符文件,因為沒有任何形式的同步,因為它們的輸出都混在一起,所以復制后的文件就是錯的。那么為了解決該問題,我們應該對所寫的程序加以改進。

if((src=open(argv[1],O_RDONLY))<0)
        {
                ……
        }
        if((des=open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0644))<0)
        {
                ……
        }
        len=lseek(src,0,SEEK_END);
        ftruncate(des,len);//創建空洞文件
        printf("len=%ld\n",len);
        int pid;
        if((pid=fork())<0)
        {
                ……
        }
        else if(pid ==0)
        {
                close(src);
                close(des);
                if((src=open(argv[1],O_RDONLY))<0)
                {
                        fprintf(stderr,"open %s failed!:%s\n",argv[1],strerror(errno));
                        return -1;
                }
                if((des=open(argv[2],O_WRONLY))<0)
                { 
                        fprintf(stderr,"open %s failed!:%s\n",argv[2],strerror(errno));
                        return -1;
                }
                lseek(src,len/2,SEEK_SET);
                lseek(des,len/2,SEEK_SET);
                while((n=read(src,buf,sizeof(buf)))!=0)
                {
                        write(des,buf,n);
                }
                close(src);
                close(des);
                exit(0); 
        }
        else
        {
                lseek(src,0,SEEK_SET);
                lseek(des,0,SEEK_SET);
                while((n=read(src,buf,sizeof(buf)))!=0) 
                {
                        write(des,buf,n);
                        if(lseek(src,0,SEEK_CUR) > len/2)
                        break;
                }
                wait(NULL);
                close(src);
                close(des);
                exit(0);
        }

這樣父、子進程就不共享同一個文件位移量,雖然打開的是同一個文件,寫的也是同一個文件,但是再實際操作中,就不會讓父子進程使用同一張文件表了。

發表評論
評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
主站蜘蛛池模板: 国产又色又爽又刺激视频 | 在线观看片免费人成视频播放 | 四虎影视永久在线看无码 | 中文字幕一区二区三区四区五区六区 | 久久国产AV无码一区二区老太 | 亚洲成AV大片大片在线播放 | 69麻豆天美精东蜜桃传媒潘甜甜 | 综合图区亚洲欧美另类图片 | 噜噜视频 | 国产v亚洲v天堂a_亚洲 | 在线āv视频 | 嫩草影院官网 | 97国产大学生情侣在线视频 | 成人H动漫精品一区二区无码 | 黄色入口网站 | 麻豆传媒视频在线播放 | 人人澡人人澡人人看添AV | 日本肥老太成熟 | 亚洲多毛女人厕所小便 | 中文字幕精品亚洲无线码VR | 强奷很舒服好爽好爽 | 正在播放 露脸 一区 | 一边摸一边桶一边脱免费视频 | 欧美乱强伦XXXXX | 亚洲AV乱码久久精品蜜桃 | 无码人妻丰满熟妇啪啪7774 | 精品人妻一区二区三区四区在线 | 欧美人与动性XXXXX杂性 | 人摸人人人澡人人超碰97 | 国产成人8x人网站 | 日韩欧美亚洲综合久久 | 久久久久久亚洲Av无码精品专口 | 亚洲人成网站77777·C0M | av第一福利在线导航 | 久久久亚洲av成人网站 | 欧美日韩在线视频免费观看 | AV国内精品久久久久影院 | 性一交一乱一伦一色一情丿按摩 | 亚洲av伊人久久青青草原 | 公交车上~嗯啊被高潮视频软件 | 人妻无码久久一区二区三区免费 |