2013-03-26 175 views
0

單挑:我不熟悉使用線程池,這可能會從下面的代碼中看出來。我的印象是,我可以將許多值推入該隊列,然後等待一個線程完成,然後轉到下一個線程,系統將處理要運行多少個線程的同步。有很多線程的線程池queueuserworkitem

我想使用ThreadPool :: QueueUserWorkItem(waitcallback,num)其中的值被迭代到動態值取決於一些先前的算法。我遇到的問題是程序崩潰時,它太高。

WaitCallback^ wcb = gcnew WaitCallBack(this, &createImage); 
for(int i = 0; i < numBlocks; i++) 
{ 
    ThreadPool::QueueUserWorkItem(wcb, i); 
} 

我得到的消息「運行時錯誤!此應用程序已請求運行時終止它在一個不尋常的方式,請聯繫應用程序的支持團隊以獲取更多信息。」

我最反感通過了numBlocks運行= 644

+1

你的代碼叫做terminate()。這通常是因爲非託管代碼拋出了一個C++異常,並沒有被捕獲。與您發佈的代碼段無關。確保使用以混合模式運行的調試器來調試代碼。 – 2013-03-26 17:22:06

+0

如果是這樣的話,它可能與我進行圖像轉換有關,因爲在我以線性方式運行任務之前,我始終能夠假定文件已關閉,正在讀取。現在,我問,這種類型的異常可能來自多個線程試圖打開同一個文件嗎? – 2013-03-26 17:53:02

+0

當然,這是行不通的。它不需要多個線程,你一定需要改進你的錯誤處理。 – 2013-03-26 17:58:34

回答

1

這很難說是什麼原因造成程序崩潰。很可能,其中一個線程拋出了異常,並導致程序失效。你必須確定你的代碼在哪裏拋出異常。

如您所知,ThreadPool::QueueUserWorkItem隊列由線程池處理的項目。但是可能有多個線程處理來自該隊列的項目。例如,您可以有20個池線程,其中15個處理您排隊的工作項。

如果你真的有很多項目需要處理,而且你希望他們一次完成一個項目,那麼爲什麼不排列一個線程來一次完成一項。我從來沒有做過託管的C++,所以我不會試着用它寫一個例子。但是,也許你能翻譯此C#代碼:

void ProcessInBackground(object state) 
{ 
    int numBlocks = (int)state; 
    for (int i = 0; i < numBlocks; ++i) 
    { 
     createImage(i); 
    } 
} 

然後你就可以把它叫做:

ThreadPool::QueueUserWorkItem(ProcessInBackground, numBlocks); 

,創建一個單獨的線程會按順序處理的項目。

我懷疑你可以很容易地將它轉換爲託管C++。

+0

我讓他們一次排隊運行1,但之後程序花了4天才完成。我需要拆分進程,以便它不是線性的,而是一次運行多個轉換(createImage(int))。我正在嘗試生成並管理createImage函數的多個線程。我可以手動完成,但我認爲QueueUserWorkItem,基於我的機器優化了程序 – 2013-03-26 15:06:01

+1

@GeneParmesan:你應該看看「Parallel.ForEach」和Task Parallel Library。那些將比使用'ThreadPool' API輕鬆完成分配線程的工作更好。 – 2013-03-26 18:40:17