2012-11-07 72 views
2

在服務器/客戶端設置中,我有一個服務器在不同套接字的少數(當前爲4)處與客戶端連接。目前,我使用select來計算set_size,但是在使用FD_SETSIZE之前,上限是多少?FD_SETSIZE與計算值

下面是一些代碼示例來說明這一點。首先建立一套:

FD_ZERO(&set); 
FD_SET(socket1, &set); 
FD_SET(socket2, &set); 
FD_SET(socket3, &set); 
FD_SET(socket4, &set); 

這裏是set_size是如何計算的:

set_size = MAX(socket1, socket2); 
set_size = MAX(set_size, socket 3); 
set_size = MAX(set_size, socket4); 
set_size += 1; 

和使用:

while ((cnt = select(set_size, &set, NULL, NULL, &t)) != -1 || errno == EINTR) { 
    if (cnt > 0) 
     // Do different stuff depending what socket is active 
    else 
     // Keep everything alive and add the sockets to the set again 
} 

最近我有添加了兩個新的插座和我可能需要在未來增加更多。什麼時候使用FD_SETSIZE而不是計算的set_size?

回答

1

我從來不擔心這件事,因爲它似乎會與首先使用select()的性能損失相比,會產生非常小的差異。

話雖如此,我認爲它總是值得計算正確的值,因爲它不是非常昂貴的計算:如果保持當前set_size在一個局部變量,你提出,這是O(1)具有非常每次添加一個fd(即比較和可能的更新)時都是低常量。刪除fd也是O(1),除了它是列表中的最後一個(在這種情況下,它是O(set_size但通常更好)。另一方面,不計算set_size意味着內核每次調用select時都必須遍歷所有FD_SETSIZE條目。由於set_size可能比FD_SETSIZE略小,因此支付較小的價值是值得的。即使set_size接近FD_SETSIZE,計算set_size是如此便宜,它可能幾乎總是仍然值得。

當然,如果您擔心在這方面的表現,您需要查看poll()而不是select()。更好的是,您需要查看epollkqueue,但這不是可移植的,因爲這些功能分別僅在Linux和FreeBSD(包括MacOS)上可用。

+0

謝謝。真的很好的解釋。目前我不擔心太多的性能,但隨着軟件使用量的增加,我可能需要研究性能改進。考慮到這一點,很高興知道從哪裏開始:) –