2014-11-24 128 views
1

我正在編寫用於管理大量UMS工作線程的UMS調度程序,並且遇到了一個非常奇怪的問題。由於某種原因,我可以創建的最大數量的UMS線程是8192(不存在普通線程的這種問題,我可以輕鬆地創建> 20 000個)。用戶模式調度程序線程的最大數量

通過調用CreateRemoteThreadEx返回的錯誤爲1450 「系統資源不足」

的PC具有以下配置:

  • 的Windows Server 2012R2數據中心x64
  • 16GB或RAM
  • 2x英特爾至強5520處理器
  • 1TB的磁盤空間

我曾嘗試以下:

  1. 提高流程工作組(無效果)通過註冊表的SystemPages的
  2. 增加數量(沒有效果,現在它被設置爲0)
  3. 我已籤免費頁面,非分頁和分頁池限制(在CreateRemoteThreadEx調用期間它們不是捱餓)
  4. 我試過在另一臺PC上(2GB內存,Inter Core 2 Duo處理器,Windows 8.1x64,幻數8192)。

下面是一個代碼示例測試:

DWORD 
UmsThreadRoutine(
    PVOID pState 
) 
{ 
    UNREFERENCED_PARAMETER(pState); 
    return 0; 
}; 

int main(int args, char **argv) 
{ 
    PCHAR pMessage = "Program End"; 
    DWORD dwErrorCode = ERROR_SUCCESS; 
    DWORD dwIteration = 0; 
    PUMS_COMPLETION_LIST pUmsCompletionList = NULL; 
    if (!::CreateUmsCompletionList(&pUmsCompletionList)) 
    { 
     pMessage = "CreateUmsCompletionList"; 
     goto EXIT_POINT; 
    } 

    for (int i = 0; i < 20000; ++i) 
    { 
     dwIteration = i; 
     LPPROC_THREAD_ATTRIBUTE_LIST pAttributes = NULL; 
     SIZE_T szAttributes = 0; 

     if (::InitializeProcThreadAttributeList(NULL, 1, 0, &szAttributes)) 
     { 
      pMessage = "InitializeProcThreadAttributeList(Size)"; 
      goto EXIT_POINT; 
     } 

     pAttributes = (LPPROC_THREAD_ATTRIBUTE_LIST)::malloc(szAttributes); 
     if (pAttributes == NULL) 
     { 
      pMessage = "malloc"; 
      goto EXIT_POINT; 
     } 
     if (!::InitializeProcThreadAttributeList(pAttributes, 1, 0, &szAttributes)) 
     { 
      pMessage = "InitializeProcThreadAttributeList"; 
      goto EXIT_POINT; 
     } 

     PUMS_CONTEXT pUmsContext = NULL; 
     if (!::CreateUmsThreadContext(&pUmsContext)) 
     { 
      pMessage = "CreateUmsThreadContext"; 
      goto EXIT_POINT; 
     } 

     UMS_CREATE_THREAD_ATTRIBUTES umsCreationAttributes = { UMS_VERSION, pUmsContext, pUmsCompletionList }; 
     if (!::UpdateProcThreadAttribute(pAttributes, 0, PROC_THREAD_ATTRIBUTE_UMS_THREAD, &umsCreationAttributes, sizeof(UMS_CREATE_THREAD_ATTRIBUTES), NULL, NULL)) 
     { 
      pMessage = "UpdateProcThreadAttribute"; 
      goto EXIT_POINT; 
     } 

     DWORD dwId = 0; 
     HANDLE hThread = ::CreateRemoteThreadEx(
      ::GetCurrentProcess(), 
      NULL, 
      0, 
      (LPTHREAD_START_ROUTINE)::UmsThreadRoutine, 
      NULL, 
      CREATE_SUSPENDED, 
      pAttributes, 
      &dwId 
     ); 
     if (hThread == NULL) 
     { 
      pMessage = "CreateRemoteThreadEx"; 
      goto EXIT_POINT; 
     } 

     ::DeleteProcThreadAttributeList(pAttributes); 
    } 

    EXIT_POINT: 
    dwErrorCode = ::GetLastError(); 
    ::printf("Program exited with Error Code '%d' on step '%s' on iteration '%d'", dwErrorCode, pMessage, dwIteration); 
} 

我運行另一臺PC上這個片段,它工作得很好(我已經創建了20000個UMS線程)。

PC配置:

  • 的Windows 8.1 x64企業
  • 英特爾酷睿i5-3470
  • 8 GB的RAM
  • 1的自由空間TB。

所以基本上這看起來像某種限制(看起來像它可以改變)。

你有什麼想法嗎?

更新:安裝最新的更新後,沒有什麼變化。

回答

2

我現在找不到它,但是在某些時候,我讀到UMS內核端實現使用英特爾的LDT來映射每個UMS線程。

8192正好是LDT表中的條目數。 LDT可以在Win7內核中以許多創造性的方式進行管理,因此可能是8192是每個進程的限制,每個線程或者每個內核的限制。您將不得不嘗試設置處理器親和度或者擁有更多UMS調度程序線程,以查看是否可以超過此限制。

+0

我打算測試一些想法,但我打了[這個](http://stackoverflow.com/questions/34913794/user-mode-scheduler-ums-returns-error-not-supported)的問題。 – AlienRancher 2016-01-21 01:57:49

+1

你是完全正確的。這裏是[UMS]的專利鏈接(http://www.patentsencyclopedia.com/app/20080320475#ixzz4YSrGPd00),它明確指出「進程中的每個用戶模式線程塊在本地描述符表中都有一個描述符」,並且這基本上限制了ums線程的最大數量。 – 2017-02-12 10:12:52