Linux fork的写时复制
這個問題是一個同學在知識星球里面提問的
看下面的代碼
#include?<stdio.h>?? #include?<stdlib.h>?? #include?<unistd.h>?? #include?<sys/types.h>?? #include?<sys/stat.h>?? #include?<fcntl.h>?? #include?<sys/wait.h> #include?<string.h>int?main(){??int?fd;??char?c[10];??char?*child?=?"#>Child.....output\n";??fd?=?open("foobar.txt",O_RDWR|O_CREAT,0666);??printf("fd:%d\n",fd);?write(fd,"foobar.txt",7);close(fd);//父進程??fd?=?open("foobar.txt",O_RDONLY,0);printf("fd:%d\n",fd);if(fork()==0)//子進程{??fd?=?1;//stdoutwrite(fd,child,strlen(child)+1);exit(0);??}??printf("fd:%d\n",fd);read(fd,c,sizeof(c));close(fd);?c[10]='\0';??printf("c?=?%s\n",c);??exit(0);?? }??先不要往下看,猜測下這個代碼的輸出是啥
特別是 fd 在fork出來的進程里面進行了修改,那是不是讀出來的內容會是不對的呢?
實際輸出如下:
weiqifa@bsp-ubuntu1804:~/linux$?gcc?forkc4.c?&&?./a.out fd:3 fd:3 fd:3 c?=?foobar #>Child.....output weiqifa@bsp-ubuntu1804:~/linux$這涉及一個知識點,叫做寫時復制,就是在使用的使用,我再分配實際的物理內存給子進程,如果沒有需要使用的資源,那我就還是用父進程的東西。
fork函數用于創建子進程,典型的調用一次,返回兩次的函數,其中返回子進程的PID是0,其中調用進程返回了子進程的PID,而子進程則返回了0,這是一個比較有意思的函數。
但是兩個進程的執行順序是不定的。fork()函數調用完成以后父進程的虛擬存儲空間被拷貝給了子進程的虛擬存儲空間,因此也就實現了共享文件等操作。
但是虛擬的存儲空間映射到物理存儲空間的過程中采用了寫時拷貝技術(具體的操作大小是按著頁控制的),該技術主要是將多進程中同樣的對象(數據)在物理存儲其中只有一個物理存儲空間,而當其中的某一個進程試圖對該區域進行寫操作時,內核就會在物理存儲器中開辟一個新的物理頁面,將需要寫的區域內容復制到新的物理頁面中,然后對新的物理頁面進行寫操作。這時就是實現了對不同進程的操作而不會產生影響其他的進程,同時也節省了很多的物理存儲器。
寫時復制的技術讓操作系統大大降低了實際的物理內存空間。
參考:
https://www.cnblogs.com/wuchanming/p/4495479.html
推薦閱讀:
專輯|Linux文章匯總
專輯|程序人生
專輯|C語言
嵌入式Linux
微信掃描二維碼,關注我的公眾號
總結
以上是生活随笔為你收集整理的Linux fork的写时复制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何按页进行PDF文档拆分
- 下一篇: 将多个pdf合并为一个