2015-02-26 37 views
1

我有一些處理大約30,000條記錄的代碼。基本輪廓是這樣的:如何在「線程池」中分割一系列值?

startRecordID = 2345; 
endRecordID = 32345; 
for(recordID=startRecordID; recordID <= endRecordID; recordID++){ 
    // process record... 
} 

現在,這種處理需要很長的時間,我想有15個線程的線程池,並給每個線程recordIDs到的進程列表,然後加入他們都結束了。

在我的代碼完成了這一以往認爲看起來是這樣的,在那裏是recordLists子陣列的陣列,以被處理的記錄每片含1/15:

<cfset numThreads = 15 /> 
<!--- keep a running list of threads so we can join them all at the end ---> 
<cfset threadlist = "" /> 
<cfloop from="1" to="#numThreads#" index="threadNum"> 
    <cfset threadName = "recordProcessing_#threadNum#" /> 
    <cfset threadlist = listAppend(threadlist, threadName) /> 
    <cfthread action="run" name="#threadName#" recordList="#recordList[threadNum]#"> 
     <cfloop from="1" to="#ArrayLen(recordList)#" index="recordIndex"> 
      <cfset recordID = recordList[recordIndex] /> 
      ... process recordID ... 
     </cfloop> 
    </cfthread> 
</cfloop> 
<!--- Join all threads before continuing ---> 
<cfthread action="join" name="#threadlist#" timeout="4000"/> 

此工作良好(雖然我也會將這個舊的代碼轉換爲cfscript :)),但是創建子數組的recordLists數組並不那麼簡單......我能想到的做法是從startRecordID- endRecordID,將每個數組添加到數組中,然後在其上運行一個ArrayDivide函數(我們已經在代碼庫中定義了該函數),將其分解爲numThreads(本例中爲15)相等的子數組。考慮到我有範圍的開始,範圍的結束以及我想要分割的線程的數量,是不是有一種更簡單的方法來分解它並將它分配給線程?

+0

只是想知道爲什麼15個線程?沉重的I/O?你有多少核心可以訪問? – Henry

+0

我建議使用你現有的循環。 –

+0

@DanBracuk - 怎麼樣?你能解釋我可以如何將線程池合併到該循環中嗎? – froadie

回答

3

(從評論..)

如果你已經再有一個數組,爲什麼環通呢?沒有內置函數,但由於數組是java,所以簡單的yourArray.subList(startIndex, endIndex)就可以做到這一點。在記錄數少於處理線程數的情況下,顯然會添加一些錯誤處理。

NB:既然是Java方法,索引從0開始(0)和endIndex獨家。另外,結果是在大多數方面CF陣列。然而,它是不可變的,即不能被修改。

<cfscript> 
    // calculate how many records to process in each batch 
    numOfIterations = 15; 
    totalRecords = arrayLen(recordsArray); 
    batchSize = ceiling(totalRecords/numOfIterations); 


    for (t=0; t < numOfIterations; t++) { 
     // calculate sub array positions 
     startAt = t * batchSize; 
     endAt = Min(startAt+batchSize, totalRecords); 

     // get next batch of records 
     subArray = recordsArray.subList(startAt, endAt); 

     // kick off a thread and do whatever you want with the array ... 
     WriteOutput("<br>Batch ["& t &"] startAt="& startAt &" endAt="& endAt); 
    } 
</cfscript> 
+0

我正在調整這個,主要是因爲我實際上沒有'recordsArray' - 我只有一個ID範圍。答案仍然有幫助。當我得到它時,我會更新。 – froadie

+0

(編輯)我上面使用'ArrayLen(recordList)'的例子。什麼是你的「範圍」對象 - 如果不是數組? – Leigh

+0

這個例子是當我有一個子數組數組時,以前的線程實現的代碼,正如後文中所解釋的那樣。我目前唯一的代碼是第一個代碼循環,其中我有一個startRecordID和一個endRecordID,需要弄清楚如何平均分配它們到線程之間的範圍。你的回答指出我的方向是正確的,我想我可能有一些工作代碼......仍然在測試 – froadie