色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);
        }

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

發表評論
評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
主站蜘蛛池模板: 四虎永久在线精品免费看 | 成年男人裸J照无遮挡无码 无码少妇人妻专区在线视频 | 扒开双腿猛进入校花免费网站 | 美女胸又www又黄的网站 | 最新中文字幕AV无码不卡 | 日韩人妻无码精品无码中文字幕 | 这里有精品可以观看 | 欧美日韩国产激情一区 | 中文字幕与邻居少妇性刺激 | 少妇高潮太爽了在线观看免费 | 亚洲精品无码久久久久苍井空国产一 | 大地资源视频在线观看 | 女人18毛片a级毛片 成·人免费午夜无码区 | 无码中文字幕日韩专区 | 亚洲日韩av无码一区二区三区人 | 波多野结衣高清一区二区三区 | 免费高清特色大片在线观看 | 伊人色综合视频一区二区三区 | 中文字幕人成无码人妻 | 小12萝8禁在线喷水观看 | 狠狠色噜噜狠狠狠狠色综合网 | 大地影院mv高清在线观看免费 | 免费国无人区码卡二卡 | 中文在线a | 无码高潮喷吹在线观看 | 国产女人的高潮国语对白 | 国产成人午夜福利院 | 新国产三级视频在线播放 | 中文字幕一区二区三区视频 | 久久AV无码精品人妻糸列 | 国产成人无码精品久久二区三区 | 极品少妇hdxx麻豆hdxx | 欧美一区二区成人片 | 日本亲子乱子伦xxxx30路 | 久草热在线观看 | 在线精品视频一区二区三四 | 偷偷碰偷偷鲁免费视频 | 人妻被黑人粗大的猛烈进出 | 无码内射中文字幕岛国片 | 成年在线网站免费观看无广告 | 欧美日韩精品成人网站二区A∨有 |