2012-01-11 90 views
0

我正在製作服務器,並使用fork()創建子進程,但我對此有所懷疑。這裏有一些:有關分叉進程的問題

  1. 爲什麼你需要關閉父進程中的子進程中的主要套接字和新的連接接受套接字? (在接受一個新的連接之後),我認爲套接字只是帶有一些id的整數,用於訪問某些系統範圍對象中的打開的套接字,這些套接字只能通過系統函數調用接受。在這種情況下,fork只會複製整數,但對打開的套接字沒有影響。
  2. 我檢查並發現,如果我在一個類方法內部派生一個進程,所有成員都被複制。那麼,我發現它是在編輯上覆制的,這是否意味着我的服務器類將被複制到使用非常量函數的每個子項中?我如何在所有這些進程之間共享一些內存(如任務列表,每個孩子在父母正在從中讀取東西時將其中的東西放入其中)?我認爲fork不適合這個功能。什麼是最好的方法?

附:我很確定我知道第二個問題的答案,即clone(),但只是想確保這是正確的功能。

回答

1
  1. 套接字在Unix中的文件描述符,他們確實是整數,由用戶所看到的,但他們確實是索引到內核每個進程維護一個表。在這個表中,每個文件描述符(FD)指的是開放文件描述(OFD),它們是在內核中維護的全系統對象。當你做fork()時,打開的文件描述符被複制,並且子節點和父節點都指向相同的OFD。有兩個指向相同OFD的FD通常不是問題,但特別是對於插座,它們可能存在細微問題,因爲只有在關閉指向它的FD時纔會關閉連接。

  2. 你應該真的考慮使用線程(如果你使用線程,不要關閉套接字!)。 clone是一個Linux系統調用,不打算直接使用。你的選擇是使用共享內存,但它有點複雜。

+0

這是非常翔實的。它確實很好地解釋了套接字。現在很清楚。其實我有一些多線程的經驗。我曾與pthreads工作,但叉似乎很好,因爲你不需要另一個功能來做這件事。但是......我現在可能會使用pthread;) – Pijusn 2012-01-11 18:11:47

0

分叉重複文件描述符,所以你要關閉重複。

的分岔也有效地將所有內存(雖然在實踐中這是寫入時複製,所以它不是很貴)。除非您明確設置了一些共享內存,否則您將完成與父進程完全分離的新進程進程

也許你打算產生一個新的線程,而不是分叉新的進程

1
  1. int是一個句柄,但是套接字本身仍然與進程相關聯。孩子主要出於安全原因關閉了監聽套接字(它並不需要它,如果孩子產生了另一個進程,那麼這個進程也會繼承套接字)。服務器進程將關閉新連接的套接字,否則連接將保持打開狀態,直到服務器進程退出(只要至少有一個進程仍然具有句柄,該套接字就存在)。

  2. 你要麼需要多線程或正確的共享內存的方式。這是樂趣開始的地方。

獨立進程之間

共享內存配備了有趣的問題,而且還提供否則無法能力(例如,您可以重新啓動主服務器進程和離開進程服務運行,這是很難得到正確的開放連接兩種不同版本的服務必須彼此交談,但允許無縫升級而無需斷開客戶端連接或中斷服務)。線程之間

共享內存是比較容易的,但是線程共享相同的一組文件描述符,這樣你就不會贏得太多在這裏。

最後,還有第三種選擇:一個事件循環觀看多個插槽,兼顧各只有東西是真正發生。查看selectpoll函數的文檔。

0

我想你可能想通過this book作爲fork()的參考。

  1. 是你需要關閉束縛在兒童和接受的套接字父聽插座。整數aka文件句柄指向真實結構see this,因此除非您希望內核在可以將數據發送到連接的客戶端的子代或父代上轉儲新連接,否則可能需要完全防止這種情況。
  2. 要共享進程之間的數據,最好的方法是共享內存。我提到你的這本書也會有相當多的信息。一般來說,如果你需要共享內存而沒有共享內存,那麼你可能想看看線程。

P.S.我不確定你指的是哪個clone()方法。對象複製通過複製構造函數完成。