2015-02-26 3 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 потоков? Тяжелый ввод-вывод? На сколько ядер вы имеете доступ? – Henry

+0

Предлагаю использовать существующий цикл. –

+0

@ DanBracuk - как? можете ли вы объяснить, как я могу включить объединение потоков в этот цикл? – froadie

ответ

3

(Из комментариев ..)

Если у вас уже есть массив, почему цикл через него снова? Нет встроенных функций, но поскольку массив представляет собой java List, простой yourArray.subList(startIndex, endIndex) сделал бы трюк. Очевидно, что некоторые ошибки обрабатываются в случае, если количество записей меньше количества потоков обработки.

NB: Так как это метод Java, индексы начинаются с нуля (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' - у меня просто есть набор идентификаторов. Ответ по-прежнему оказывается полезным. Я обновлю, когда получу его работу. – froadie

+0

(Edit) Я ушел с примера выше, который использовал 'ArrayLen (recordList)'. Каков ваш объект «диапазон» - если не массив? – Leigh

+0

Этот пример был кодом предыдущей реализации потоковой передачи, когда у меня был массив подматриц, как объяснялось в сообщении. Единственным кодом, который я имел в настоящее время, был первый цикл кода, в котором у меня был startRecordID и endRecordID, и вам нужно было выяснить, как равномерно распределять диапазон между ними для потоков. Ваш ответ указал мне в правильном направлении, и я думаю, что у меня может быть какой-то рабочий код ... все еще тестирование – froadie

Смежные вопросы