日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

多进程同时写一个文件会怎样?分别用write和fwrite去观察现象

發(fā)布時間:2025/6/15 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多进程同时写一个文件会怎样?分别用write和fwrite去观察现象 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、問題還原
在多進程的環(huán)境下,父子進程同時去寫一個文件,例如父進程每次寫入aaaaa,子進程每次寫入bbbbb,問題是會不會出現(xiàn)寫操作被打斷的現(xiàn)象,比如出現(xiàn)aabbbaaabb這樣交替的情況?

二、結(jié)論
1:使用write系統(tǒng)調(diào)用的情況下,不會出現(xiàn)內(nèi)容交叉的情況。?
2:使用fwriteANSIC標準C語言函數(shù),會出現(xiàn)內(nèi)容交叉的情況。

三、實驗過程
實驗環(huán)境:
操作系統(tǒng): RedHat Linux 7.0

實驗過程:
1:打開一個文件,fork一個子進程,父子進程同時寫文件,父進程寫入a,子進程寫入b。

2:分別用write和fwrite去觀察現(xiàn)象。

實驗現(xiàn)象
write:不會出現(xiàn)數(shù)據(jù)交叉的情況,而且父子進程交替執(zhí)行寫入。
1:測試代碼如下:

#include <unistd.h> #include <stdio.h> #include <string.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h> #include <unistd.h> #include <sys/time.h> #include<sys/wait.h>int main(int argc,char * argv[]) {struct timeval start,end;int times = argc > 1 ? atoi(argv[1]):10000; ?//通過參數(shù)傳入需要寫入的字節(jié)數(shù)int stat;int fd;int childpid;int i;for(i=0 ;i<1; i++){if(childpid = fork())break;}if(childpid == -1){perror("failed to fork\n");return 1;}fd = open("tmp.dat",O_WRONLY|O_CREAT|O_APPEND,0666);if(fd < 0){perror("failed to open\n");return 1;}gettimeofday(&start,NULL); ? ? ? ? ?//測試下時間if(childpid > 0){char *buf = (char*)malloc(times);for(int i = 0;i < times;++i) {buf[i] = 'a';}strcat(buf,"\n");for(i=0; i<10; i++){usleep(1000);write(fd,buf,strlen(buf));}wait(&stat);}else{char *buf = (char*)malloc(times);for(int i = 0;i < times;++i) {buf[i] = 'b';}strcat(buf,"\n");for(i=0; i<10; i++){usleep(1000);write(fd,buf,strlen(buf));}}close(fd);gettimeofday(&end,NULL);int timeuse = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;printf("UseTime: MicroSeconds:%d us and ?Seconds:%d s\n",timeuse,end.tv_sec-start.tv_sec);return 0; }


2:編譯運行

$ ?gcc file.c -std=c99 -o file $ ./file 100


3:結(jié)果

可以發(fā)現(xiàn)首先沒有出現(xiàn)交叉的情況,并且父子進程是交替寫入的,即一行a,一行b。

fwrite:在寫入的字節(jié)數(shù)為500的時候就會出現(xiàn)交叉的情況(當然,500并不是最準確的數(shù)字,只是我測試500的時候已經(jīng)出現(xiàn)了)。
1:測試代碼如下:

#include <unistd.h> #include <stdio.h> #include <string.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h> #include <unistd.h> #include <sys/time.h> #include <sys/wait.h>int main(int argc,char * argv[]) {struct timeval start,end;int times = argc > 1 ? atoi(argv[1]):10000;int stat;int fd;int childpid;int i;for(i=0 ;i<1; i++){if(childpid = fork())break;}if(childpid == -1){perror("failed to fork\n");return 1;}FILE *fp = NULL;fp = fopen("tmpfp.dat","ab");if(fp == NULL) {system("touch tmpfp.dat");}gettimeofday(&start,NULL);?if(childpid > 0){char *buf = (char*)malloc(times);for(int i = 0;i < times;++i) {buf[i] = 'a';}strcat(buf,"\n");for(i=0; i<10; i++){usleep(1000);fwrite(buf,strlen(buf),1,fp);}wait(&stat);}else{char *buf = (char*)malloc(times);for(int i = 0;i < times;++i) {buf[i] = 'b';}strcat(buf,"\n");for(i=0; i<10; i++){usleep(1000);fwrite(buf,strlen(buf),1,fp);}}fclose(fp);gettimeofday(&end,NULL);?int timeuse = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;printf("UseTime: MicroSeconds:%d us and Seconds:%d s\n",timeuse,end.tv_sec-start.tv_sec);return 0; }


2:編譯運行

$ ?gcc fileFP.c -std=c99 -o Filefp $ ./Filefp 500


3:結(jié)果

用一個sed的表達式判斷下是否出現(xiàn)了交叉現(xiàn)象,因為我們是以行寫入的,所以每行的開頭不是a就是b,拿出所有a開頭的行,看里面是否有包含b的。

$ sed -n '/^a.*$/p' tmpfp.dat | grep b// '/^a.*$/p' ?表示以a開頭 // grep b ? 表示過濾出包含b的行


可以看到,已經(jīng)出現(xiàn)了一行a中混入了b,因此fwrite在多進程的情況下操作同一個fd是會出現(xiàn)問題的。

四、反思
1:為什么write不會出現(xiàn)問題但是fwrite卻出現(xiàn)了問題?

答:write是Linux操作系統(tǒng)的系統(tǒng)調(diào)用,fwrite是ANSIC標準的C語言庫函數(shù),fwrite在用戶態(tài)是有緩沖區(qū)的。因此需要鎖機制來保證并發(fā)環(huán)境下的安全訪問。?
http://www.cnblogs.com/ldp-web/archive/2011/10/21/2220180.html

2:如果兩個進程同時write一個socket會怎樣?

答:就像隊列一樣,一個進程寫完另一個進程才能寫,數(shù)據(jù)上不會有問題。?
http://stackoverflow.com/questions/1981372/are-parallel-calls-to-send-recv-on-the-same-socket-valid

參考資料:

http://bbs.chinaunix.net/thread-804742-1-1.html

http://www.chinaunix.net/old_jh/23/829712.html

https://www.nowcoder.com/questionTerminal/869cae279aa84d8b8e9e50cf1084830b
?

《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的多进程同时写一个文件会怎样?分别用write和fwrite去观察现象的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。