2010-04-28 98 views
10

服務器本質上是一個運行無限循環偵聽端口的後臺進程嗎?例如:服務器是作爲後臺進程運行的無限循環嗎?

while(1){ 
    command = read(127.0.0.1:xxxx); 
    if(command){ 
     execute(command); 
    } 
} 

當我說服務器時,我顯然不是指物理服務器(計算機)。我指的是MySQL服務器,或Apache等。

完全披露 - 我沒有時間戳穿任何源代碼。實際的代碼示例非常棒!

+1

不遠處fromt他真相..但是讀取通常是對系統的阻塞讀取,只有當它返回時纔會返回。沒有收到數據==沒有執行。 – eaanon01 2010-04-28 12:57:19

+0

@ eaanon01 - if(command)基本上是我說「如果收到數據」的方式。 – Tony 2010-04-28 14:30:40

+1

..爲什麼標記C? – 2010-04-29 08:31:28

回答

6

這或多或少是服務器軟件的一般用途。

通常它會變得更加複雜,因爲無限循環「only」接受連接,每個連接通常可以處理多個「命令」(或者在使用的協議中調用的任何東西),但基本思想大致就是這樣。

+0

你是否基本上說我的僞代碼+線程是非常正確的? – Tony 2010-04-28 14:27:54

+0

@Tony:是的。當然,僞代碼意味着仍然有許多細節可以正確使用,但這就是主意。 – 2010-04-28 15:35:01

+0

不完全。剩下的是_how_。 – 2010-04-29 19:15:47

2

在說話的時候,是的。服務器只是「永遠循環」並提供服務的東西。但是,通常情況下,您會發現「守護進程」會執行諸如將STDOUT和STDERR打開到文件句柄或/ dev/null以及其他雙重分支之類的操作。從某種意義上說,你的代碼是一個非常簡單的「服務器」。

4

有三種「服務器」 - 分叉,線程和單線程(非阻塞)。它們通常都會按照您展示的方式循環播放,不同之處在於需要提供服務時會發生什麼。

分叉服務就是這樣。對於每個請求,調用fork(),創建一個處理請求的新子進程,然後退出(或保持活動狀態,以處理後續請求,具體取決於設計)。

線程服務就像分叉服務,但不是一個全新的進程,而是創建一個新的線程來服務請求。像叉子一樣,有時線程會留下來處理後續的請求。性能和佔用空間的差異僅僅是線程和叉的區別。根據服務於客戶端的內存使用情況(而不是而不是)(通常情況下會更改),通常最好不要克隆整個地址空間。這裏唯一增加的複雜性是同步。

單個進程(又名單線程)服務器將僅分叉一次以守護進程。它不會產生新的線程,它不會產生子進程。它將繼續輪詢()套接字以找出文件描述符何時準備好接收數據,或者有數據可用於處理。每個連接的數據保存在自己的結構中,由各種狀態(寫入,等待ACK,讀取,關閉等)標識。這可以是一個非常有效的設計,如果做得好。在準備工作時,您可以使用單個進程和事件循環爲請求提供服務,而不是在等待工作時阻塞多個子進程或線程。

有些情況下單線程服務會產生多個線程,但是其他線程不能處理傳入的請求,有人可能會(例如)在線程中設置本地套接字,以允許管理員獲得狀態的所有連接。

對於非阻塞http服務器的一點點搜索會產生一些有趣的手寫網頁服務器,編寫爲代碼高爾夫挑戰。

總之,不同的是一旦進入無限循環發生的事情,而不僅僅是無限循環:)

+1

很好的解釋。 – Tony 2010-04-29 18:07:06