Apache 性能最優化分析(4)_Windows教程

      編輯Tag賺U幣
      教程Tag:暫無Tag,歡迎添加,賺取U幣!
       但這種實現會引起嚴重的饑餓問題。由于多個子進程同時執行這個循環,它們將在select中阻塞。當任何socket上出現一個請求時,所有被阻塞的進程將復蘇,并從select返回(蘇醒進程的數量取決于操作系統和時間)。它們將繼續執行并試圖接受這個連接,但只有一個進程會成功(假設目前仍只有一個連接),其余進程將阻塞在accept中。這將把所有失敗的進程鎖定,使它們只為一個socket上的請求服務。它們會一直被阻塞,直到在那個socket上出現足夠的請求把它們喚醒。這一饑餓問題首先在PR#467被提出。至少有兩種解決它的方法

        一種方案是使用非阻塞的socket。這種情況下,accept不會阻塞子進程,它們將會立即返回。但這種方案會造成CPU時間的浪費。假設有十個在select中的空閑進程,而后到來了一個連接請求。九個進程將蘇醒、試圖接受連接、失敗,并返回select,這些進程實際什么都沒做。而且如果在這期間,其他socket上出現請求,沒有哪個進程會為它服務。總而言之,這種方案不是十分有效,除非您擁有和空閑子進程數目相當的CPU--恐怕不切實際。

        另一種方案被Apache采納。這種方案串行化(serialize)對內層循環的調用。代碼如下所示(改進的部分被加粗顯示):

      for (;;) {
      accept_mutex_on ();
      for (;;) {
      fd_set accept_fds;

      FD_ZERO (&accept_fds);
      for (i = first_socket; i <= last_socket; ++i) {
      FD_SET (i, &accept_fds);
      }
      rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
      if (rc < 1) continue;
      new_connection = -1;
      for (i = first_socket; i <= last_socket; ++i) {
      if (FD_ISSET (i, &accept_fds)) {
      new_connection = accept (i, NULL, NULL);
      if (new_connection != -1) break;
      }
      }
      if (new_connection != -1) break;
      }
      accept_mutex_off ();
      process the new_connection;
      }
       
        
      accept_mutex_on和accept_mutex_off 兩個函數實現了互斥量(mutual exclusion semaphore),在任意時刻只能有一個子進程擁有互斥量。多種方法可以實現互斥量。在src/conf.h(1.3版之前)或src/include/ap_config.h(1.3版及以后)可以作出以下選擇。一些系統不提供任何互斥方法。在這些系統上使用多個Listen命令是不保險的。

      來源:網絡搜集//所屬分類:Windows教程/更新時間:2013-04-15
      相關Windows教程