2013-02-18 23 views
1

我正在處理中間處理線程的生產者消費者問題。當我運行這些應用程序中的200個時,它會在大量連接超時時將系統鎖定在win7中。不幸的是,我不知道如何調試它。系統無響應,我必須使用電源按鈕重新啓動。它可以在我的Mac上正常工作,奇怪的是,它在安全模式下的窗口中工作正常。如果足夠的活躍,可以boost :: mutex鎖定一個操作系統嗎?

我使用boost 1.44,因爲這是主機應用程序使用的。

這是我的隊列。我的意圖是隊列的大小是同步的。我已經操縱這個來使用timed_wait來確保我沒有丟失通知,儘管我沒有看到效果上的差異。

class ConcurrentQueue { 
public: 
    void push(const std::string& str, size_t notify_size, size_t max_size); 
    std::string pop(); 

private: 
    std::queue<std::string> queue; 
    boost::mutex mutex; 
    boost::condition_variable cond; 
}; 

void ConcurrentQueue::push(
    const std::string& str, size_t notify_size, size_t max_size) { 
    size_t queue_size; 
    {{ 
     boost::mutex::scoped_lock lock(mutex); 
     if (queue.size() < max_size) { 
      queue.push(str); 
     } 
     queue_size = queue.size(); 
    }} 
    if (queue_size >= notify_size) 
     cond.notify_one(); 
} 

std::string ConcurrentQueue::pop() { 
    boost::mutex::scoped_lock lock(mutex); 
    while (!queue.size()) 
     cond.wait(lock); 
    std::string str = queue.front(); 
    queue.pop(); 
    return str; 
} 

這些線程使用下面的隊列來處理和使用libcurl發送。

boost::shared_ptr<ConcurrentQueue> queue_a(new ConcurrentQueue); 
boost::shared_ptr<ConcurrentQueue> queue_b(new ConcurrentQueue); 

void prod_run(size_t iterations) { 
    try { 
     // stagger startup 
     boost::this_thread::sleep(
       boost::posix_time::seconds(random_num(0, 25))); 
     size_t save_frequency = random_num(41, 97); 
     for (size_t i = 0; i < iterations; i++) { 
      // compute 
      size_t v = 1; 
      for (size_t j = 2; j < (i % 7890) + 4567; j++) { 
       v *= j; 
       v = std::max(v % 39484, v % 85783); 
      } 
      // save 
      if (i % save_frequency == 0) { 
       std::string iv = 
           boost::str(boost::format("%1%=%2%") % i % v); 
       queue_a->push(iv, 1, 200); 
      } 
      sleep_frame(); 
     } 
    } catch (boost::thread_interrupted&) { 
    } 
} 

void prodcons_run() { 
    try { 
     for (;;) { 
      std::string iv = queue_a->pop(); 
      queue_b->push(iv, 1, 200); 
     } 
    } catch (boost::thread_interrupted&) { 
    } 
} 

void cons_run() { 
    try { 
     for (;;) { 
      std::string iv = queue_b->pop(); 
      send_http_post("http://127.0.0.1", iv); 
     } 
    } catch (boost::thread_interrupted&) { 
    } 
} 

我對這種方式使用互斥的理解不應該使系統無響應。如果有的話,我的應用程序將陷入僵局並永遠睡眠。

有沒有辦法讓其中的200個同時創建一個場景,但情況並非如此?

更新:

當我重新啓動電腦,大部分我需要重新插拔的USB鍵盤的時間讓它作出迴應。鑑於司機的評論,我認爲這可能是相關的。我嘗試更新北橋驅動程序,儘管它們是最新的。我會看看是否有其他需要關注的驅動程序。

更新:

我看過的內存,非分頁池,CPU,處理,港口和他們都不是在在系統響應在任何時間以驚人的速度。最後可能會出現尖峯,儘管這對我來說是不可見的。

更新:

當系統掛起,它停止渲染和不鍵盤響應。它呈現的最後一幀雖然保持不變。系統聽起來像仍在運行,當系統恢復時,事件查看器中沒有任何內容說它崩潰了。沒有故障轉儲文件。我解釋這是因爲操作系統被阻止執行。

+0

「奇怪的是,它在安全模式下的窗戶中工作正常」 - 這表明某些第三方驅動程序正在搞砸。可能是防病毒或防火牆。您可以嘗試卸載這些類型的包,以查看事後突然開始工作。 – 2013-02-18 18:37:41

+0

你看過內存使用情況了嗎?如果應用程序使用大量內存,則可能會發現系統無響應。以安全模式運行將減少系統的負載。但我同意,AV或防火牆似乎是一個可能的候選人 - 尤其是AV。 AV軟件將涉及很多事情,並且通常可能會使系統無法響應,只需通過「所有事情都必須經過這個狹窄的空洞」類型的行爲。 – 2013-02-18 18:49:02

+0

@MichaelBurr根據驅動程序更新了評論。我會試着看看下面的內容。謝謝你的評論! – 2013-02-18 18:54:35

回答

1

互斥鎖鎖定其他使用相同鎖的應用程序。操作系統使用的任何互斥鎖都不應該(直接)適用於任何應用程序。

當然,如果互斥體是以某種方式使用操作系統實現的,那麼它可能會調用操作系統,從而使用CPU資源。但是,互斥鎖不應該導致比使用CPU資源的應用程序更糟糕的行爲。

當然,如果以不恰當的方式使用鎖定,則應用程序的不同部分會死鎖,因爲函數1獲取鎖定A,然後函數2獲取鎖定B.如果功能1嘗試獲取鎖定B,並且函數2試圖在釋放它們各自的鎖之前獲取鎖A,則會產生死鎖。這裏的訣竅是始終以相同的順序獲取多個鎖。因此,如果您同時需要兩把鎖,請始終首先獲取鎖A,然後鎖定B.

Deadlockin不應該對操作系統造成影響 - 如果有的話,它會使它更好,但如果應用程序在某種情況下出現死鎖,那麼通過調用操作系統可能會導致問題 - 例如如果鎖定是通過以下方式完成的:

while (!trylock(lock)) 
{ 
     /// do nothing here 
} 

它可能會導致系統使用高峯。

+0

但特別是如果應用程序發生死鎖(即所有線程都進入停止狀態),操作系統永遠不會無響應。除非Windows調度器比我想象的更糟糕,但這又會與它在安全模式下工作的方面相沖突。 – 2013-02-18 18:39:58

+0

完全同意。 – 2013-02-18 18:46:52

+0

我想知道爲什麼你包含關於死鎖的段落呢?我可能忽略了一些重要的東西,但是... – 2013-02-18 18:54:38

相關問題