nickdelphi777
asked on
Delphi Divide a TStringList Contents Evenly into an array
Hey Guys,
I am attempting to divide a tstringlist of accounts evenly among 10 threads.
I am inserting the "batches" of accounts into different arrays.
So if i had 30 accounts, i would be dividing the list up into batches of 3 accounts and inserting them into their appropriate account array.. that way each thread can process 3 accounts and speed up things
problem I am running into.. is when the division is not even.. I've tried 3 different variations of code but when i change up the amount of accounts i get all funky results. I am hoping one of you have a very clean and simple way to do this without any errors.. regardless of how many accounts i use.
Remember i am only using 10 threads.. so essentially the list has to be split up between 10 threads evenly.
I am attempting to divide a tstringlist of accounts evenly among 10 threads.
I am inserting the "batches" of accounts into different arrays.
So if i had 30 accounts, i would be dividing the list up into batches of 3 accounts and inserting them into their appropriate account array.. that way each thread can process 3 accounts and speed up things
problem I am running into.. is when the division is not even.. I've tried 3 different variations of code but when i change up the amount of accounts i get all funky results. I am hoping one of you have a very clean and simple way to do this without any errors.. regardless of how many accounts i use.
Remember i am only using 10 threads.. so essentially the list has to be split up between 10 threads evenly.
Just round-robin them.
ASKER
Thats not really what I'm after...
ASKER
Nevermind.. it popped in my head.. just loop through entire list and keep adding to the threads.. 1 to 10, 1 to 10:
imageamount := memo1.lines.count;
threads :=10;
icount := 0;
for i := 0 to imageamount-1 do begin
memo2.lines.add('Insert '+memo1.lines[i]+ ' into '+inttostr(icount));
if(icount = threads-1) then begin
icount := 0;
end else begin
inc(icount);
end;
end;
Compact code:
imageamount := memo1.lines.count;
threads :=10;
for i := 0 to imageamount-1 do begin
memo2.lines.add('Insert '+memo1.lines[i]+ ' into '+inttostr(i mod threads));
end;
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
you don't even need that, just use Otl
use a pipeline from omnithreadlibrary ...
http://otl.17slon.com/index.htm
you only need 1 stage, this pipeline can buffer up to 10000 elements
optionally add an message proc
Numtasks indicates 10 threads
Loading the queue:
the thread processing code
use a pipeline from omnithreadlibrary ...
http://otl.17slon.com/index.htm
you only need 1 stage, this pipeline can buffer up to 10000 elements
optionally add an message proc
Numtasks indicates 10 threads
fPipeLine :=
Parallel.PipeLine
.Throttle(10000)
.Stage(
TaskProcessItem, Parallel.TaskConfig.OnMessage(MsgProcessItem)
).NumTasks(10)
.Run;
Loading the queue:
for I := 0 to Strings.Count-1
fPipeLine.AddInput(Strings[I]);
the thread processing code
procedure TaskProcessItem(const input, output: IOmniBlockingCollection; const task: IOmniTask);
Value: TOmniValue;
begin
while not Task.Terminated do
begin
if input.TryTake(Value, 1000) then
begin
// Thread processing code:
// string for this is : Value.AsString
// optionally send a message
task.Comm.Send(0, 'Processed item : ' + Value.AsString);
end;
end;
end;
procedure MsgProcessItem(const task: IOmniTaskControl; const msg: TOmniMessage);
begin
fNotifyEvent(Self, msg.MsgData.AsString);
end;
the 10 threads will take the next item when they have processed the previous
if no items are in the queue, they wait for 1 second and then retry
the next thing about this pipeline technique is that you don't need to divide anything yourself
the numtasks (15) would setup 15 threads.
numtasks(2) would only setup 2 threads
if no items are in the queue, they wait for 1 second and then retry
the next thing about this pipeline technique is that you don't need to divide anything yourself
the numtasks (15) would setup 15 threads.
numtasks(2) would only setup 2 threads
@nickdelphi777: Your code IS the round-robin algorithm.
ASKER
So if I have 15 accounts.. i do not want it to divide up by 2. and only use 7 threads.. I would like it to put say 1 account in most.. then 2 here.. and 2 there.
please help i have been stuck with this for hours