久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久

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

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

在我們(men)學(xue)習(xi)IO的(de)時(shi)候,曾經利用文(wen)件(jian)(jian)IO函數(shu),標準IO函數(shu)都實現(xian)了對(dui)文(wen)件(jian)(jian)的(de)拷貝(bei),那么(me)在我們(men)學(xue)習(xi)過(guo)進程間通信后,就可(ke)(ke)以創建多個(ge)(ge)進程來完成(cheng)對(dui)同一個(ge)(ge)文(wen)件(jian)(jian)的(de)讀寫(xie)。例如讓父進程寫(xie)文(wen)件(jian)(jian)的(de)前(qian)半(ban)部分,子(zi)進程來寫(xie)文(wen)件(jian)(jian)的(de)后半(ban)部分,因為兩個(ge)(ge)進程間是可(ke)(ke)以并(bing)發執行的(de),所以將會節約一部分時(shi)間,提(ti)高執行的(de)效率。那么(me)怎樣才能(neng)實現(xian)這個(ge)(ge)功能(neng)?

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

首先來看下用文件(jian)IO函數實(shi)現拷貝(bei)文件(jian)的(de)程序:

#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;
    &nbsp; &nbsp;         }

        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;
&nbsp;       }

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

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);
 &nbsp;     ; }

是(shi)不是(shi)只(zhi)要這(zhe)(zhe)樣寫就可以實現功能?實踐證(zheng)明這(zhe)(zhe)樣寫不行的,那(nei)么為什(shen)么這(zhe)(zhe)樣寫不可以呢?

子(zi)進(jin)(jin)(jin)(jin)(jin)程(cheng)(cheng)(cheng)和父(fu)(fu)進(jin)(jin)(jin)(jin)(jin)程(cheng)(cheng)(cheng)繼(ji)續執(zhi)行fork之后的指令。子(zi)進(jin)(jin)(jin)(jin)(jin)程(cheng)(cheng)(cheng)是父(fu)(fu)進(jin)(jin)(jin)(jin)(jin)程(cheng)(cheng)(cheng)的復制(zhi)品。子(zi)進(jin)(jin)(jin)(jin)(jin)程(cheng)(cheng)(cheng)獲(huo)得父(fu)(fu)進(jin)(jin)(jin)(jin)(jin)程(cheng)(cheng)(cheng)數(shu)據空(kong)間、堆棧的復制(zhi)品。注意,這是子(zi)進(jin)(jin)(jin)(jin)(jin)程(cheng)(cheng)(cheng)所擁有(you)的拷貝,父(fu)(fu)、子(zi)進(jin)(jin)(jin)(jin)(jin)程(cheng)(cheng)(cheng)并(bing)不共享(xiang)這些存(cun)儲(chu)空(kong)間部分。那么跟本(ben)例(li)相(xiang)關(guan)的一(yi)條fork特性(xing)就是由父(fu)(fu)進(jin)(jin)(jin)(jin)(jin)程(cheng)(cheng)(cheng)打開的文(wen)件(jian)描(miao)述符也被復制(zhi)到子(zi)程(cheng)(cheng)(cheng)序中。父(fu)(fu)、子(zi)進(jin)(jin)(jin)(jin)(jin)程(cheng)(cheng)(cheng)的每個(ge)相(xiang)同的打開描(miao)述符共享(xiang)一(yi)個(ge)文(wen)件(jian)表項。

在unix高級(ji)環境編(bian)程中有這樣一幅圖(tu)

這種共享文(wen)件(jian)的(de)(de)方式使父(fu)、子(zi)進(jin)程(cheng)(cheng)對同一(yi)個文(wen)件(jian)使用(yong)了一(yi)個文(wen)件(jian)位移量。當父(fu)進(jin)程(cheng)(cheng)是其(qi)標(biao)準輸出重(zhong)新(xin)定向,那么子(zi)進(jin)程(cheng)(cheng)寫到該(gai)(gai)(gai)標(biao)準輸出時,它(ta)將更(geng)新(xin)與父(fu)進(jin)程(cheng)(cheng)共享的(de)(de)該(gai)(gai)(gai)文(wen)件(jian)的(de)(de)位移量。當程(cheng)(cheng)序中,父(fu)、子(zi)進(jin)程(cheng)(cheng)寫到同一(yi)個描述符文(wen)件(jian),因為(wei)沒有任何形式的(de)(de)同步,因為(wei)它(ta)們(men)的(de)(de)輸出都混在一(yi)起,所以復(fu)制后的(de)(de)文(wen)件(jian)就是錯(cuo)的(de)(de)。那么為(wei)了解決該(gai)(gai)(gai)問題,我們(men)應該(gai)(gai)(gai)對所寫的(de)(de)程(cheng)(cheng)序加(jia)以改進(jin)。

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);
&nbsp; &nbsp;     }

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

發表評論
評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)