在我們寫linux服務器的時候,fork()子進程那是相當容易會碰到的,但是最近碰到了一個問題:
場景描述:
在主進程中處理通信協議,如果用戶要加入一個不存在的房間,那麼我們就會fork()一個子進程,然後所以的協議,我們都放到子進程中去處理,那麼父進程也就可以中斷了.
這個時候:
父進程的socket,我們在子進程中絕對不會用到.
然後父進程可以關閉這個socket.
問題來了???
我們是否需要在子進程中來關鍵這個socket。
其實我個人一直是比較傾向於不需要在子進程中關閉這個socket的,因爲fork()一個子進程那是相當的快,爲何這麼快,因爲原則是用時拷貝,就是隻有子進程需要用到父進程的東西的時候,纔會從內存中拷貝一份出來.
爲此我們來進行測試:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
int main()
{
//爲了方便測試,我們用文件IO進行測試是一樣的.
FILE * fs = fopen("msg.txt","ab+");
const char *msg = "this is first msg \n" ;
fwrite(msg,1,strlen(msg),fs);
pid_t pid = fork();
// 父進程中,我立刻fclose(); 然後子進程在重新fwrite,看這個信息能不能重新寫進去.
//
if(pid > 0)
{
//父進程
fclose(fs);
sleep(100);//暫停100秒
std::cout << "父進程已經結束" << std::endl;
}
else if(pid == 0)
{
//子進程
sleep(20); //子進程先暫停20秒,然後在嘗試寫
const char *msg = "msg form child process \n";
fwrite(msg,strlen(msg),1,fs);
fclose(fs);
std::cout << "子進程已經結束" << std::endl;
}
else
{
//創建進程失敗
std::cout << "創建進程失敗" << std::endl;
}
}
文件裏面文本內容的截圖如下所示:
這說明了,fork()之後的動作,絲毫不影響子進程的任何狀態。
那麼子進程這個寫時拷貝的原則是什麼呢????
???
父進程如果new一個對象,子進程不適用,也不析構new出來的這個對象,是否會導致內存泄露,
歷史遺留問題,暫時還沒整明白,後續再測試!
fork()之前的狀態應該肯定要保存,不然上面的代碼就沒法保存