2012-03-22 82 views
1

我使用Pthreads在C中使用多線程設計多cleint Web服務器,我有一個Masterthread,它在循環中進行監聽,一個連接產生了一個新的線程來完成一個函數的服務,而Masterthread繼續監聽連接。爲什麼accept()系統調用不接受新的連接,直到關閉以前的連接套接字

正如我從調試中注意到的,它一次只服務一個連接,Accept()系統調用正在等待該連接關閉,然後它會產生隊列中的下一個連接。

它的表現就好像它是一個單線程的Web服務器。

void *ServeThread(void *param) 
{ int tsk; 
    tsk = (int)param; 

    /* here im serving the connection (tsk), and then close it */ 
} 

void *MakeThreadPool(void *param) 
{ 

    for(;;) { 
     length = sizeof(cli_addr); 
     if((socketfd = accept(listenfd, (struct sockaddr *)&cli_addr, &length)) < 0) { 
      exit(1); 
                } 
    temps=socketfd; 
    rc = pthread_create(&Thread[i++],NULL,ServeThread,(void *)temps); 

         } 
} 

我怎樣才能使accpet()contine在產生連接時產生連接而沒有等待前一個連接完成?

+1

你的分析是錯誤的,這段代碼不會等待現有的連接/線程完成。雖然有可能通過調試應用程序來影響這一點(也許所有線程都在調試器中停下來時停止)。找到另一種調試方法(例如簡單的printf),和/或顯示更多的代碼,並描述如何測試它。 – nos 2012-03-22 14:49:45

+0

插座是否處於NONBLOCKING模式? – snibu 2012-03-22 15:03:24

+0

我刪除了關閉(套接字),我用網絡瀏覽器連接到網絡服務器,並輸入了網絡服務器的URL,並且我打開了一個新標籤並連接了網絡服務器。並且只有一個選項卡連接「當然它沒有關閉連接」,但另一個正在等待「沒有(在選項卡中傳輸數據消息)」,如連接的那個。 – CodeRed 2012-03-22 15:28:55

回答

0

您的觀察結果不正確,accept(2)不等待已建立的TCP連接完成。你看到的可能是線程調度工件 - 主線程被新生成的線程搶佔,直到該線程完成纔會運行。

通常,thread-per-connection是一種可行的策略,但您可能希望在接受連接之前創建一個線程池,而不是每次都啓動一個新線程。

0

做一個malloc將文件描述符放入它 - 這將防止您遇到的競爭條件。新創建的線程在完成時與free有合同。另外(和更好的解決方案)是有一個線程池已準備好去。使用互斥鎖和隊列,以便在準備處理時可以將其選中。

更好的還有可能更簡單的實現,創建一堆線程 - 每個線程圍繞accept有一個互斥體。如果有必要,主線程可以將該列表加滿,或者要求一些優雅地終止,如果很多。

0

默認情況下,TCP套接字處於阻塞狀態。你有沒有設置這些標誌?

x=fcntl(socket,F_GETFL,0);    
    fcntl(socket,F_SETFL,x | O_NONBLOCK); 
+0

OP想要accept()來阻塞。 – 2012-03-22 15:31:11

相關問題