2017-02-18 64 views
0

我已經運行在Visual Studio 2015年C++創造循環線程時錯誤

#include <thread> 
#include <vector> 
#include <iostream> 
using namespace std; 

int main() { 

    for (int i = 0; i < 10000; i++) { 
     cout << "Loop: " << i << endl; 

     vector<thread> threads; 
     for (int j = 0; j < 8; j++) { 
      try { 
       threads.push_back(thread([]() {int a = 4; a++; })); 
      } 
      catch (const system_error &se) { 
       cout << se.what() << endl; 
       exit(1); 
      } 
     } 

     for (int j = 0; j < 8; j++) { 
      threads.at(j).join(); 
     } 
    } 

    return 0; 
} 

以下幾千元的循環已經在運行該程序後,當一個問題捕獲與輸出SYSTEM_ERROR:

... 
3994 
3995 
3996 
3997 
3998 
resource unavailable try again: resource unavailable try again 

我知道有最大數量的線程可以同時運行,但在這種情況下,只有8個正在同時運行,之後它們被銷燬。可以創建的總數有最大值嗎?

我試着在Linux上用g ++運行上面的代碼,它運行良好,只有在windows(包括visual studio和mingw)上纔會出現錯誤。任何幫助? 謝謝。

+0

'push_back'副本,你可能想用'emplace_back'再試一次 – Mgetz

+0

給它一個Mgetz,但它沒有什麼區別 –

+2

@SamVarshavchik請不要在評論中留言。事實是C++是大多數窗口的基礎,VC++團隊在WINDIV中擁有非常感興趣的客戶。 – Mgetz

回答

1

這裏發生的事情最好通過了解如何在Windows上創建線程來描述。

創建時的每個線程都會被賦予一個default 1Mb stack size。你會注意到你得到大約3998個線程,這對應於大約3.9Gb的用戶地址空間。這不是偶然的,因爲這對應於64位窗口(內核空間爲64位)下32位進程可用的大部分完整4Gb用戶地址空間。額外的空間是可執行文件和必要的系統DLL被加載到的地方。

通過將構建版本更改爲64位,您已大規模擴展了該地址空間。具有1Mb堆棧的10000個線程是存儲桶中的一個分區,limiter becomes non-pagable kernel memory儘管1Mb堆棧可以並將被分頁,導致系統減慢抓取速度。

+0

對不起,但我在這裏錯過了一些東西...正如原來的帖子所說,永遠不應該有超過8個線程存在(如果包含'main'本身,則爲9) - 所有8個線程在單個外部循環迭代的範圍內被創建*和*銷燬。那麼爲什麼會增加資源使用?再次,如果我錯過了這個觀點,很抱歉。 –

+0

@ G.M。因爲連接並不意味着線程從操作系統的角度來解除分配(雖然線程'HANDLE'必須關閉),只是他們加入了。像Windows上的許多事情一樣,我會懷疑線程銷燬是異步的,但創建是同步的。因此,操作系統會很樂意讓您根據您理解的方式創建儘可能多的線程。因此,根據我的估計,TEB可能正在等待IPC'DISPATCH發生的下一個DPC遭到破壞。 – Mgetz