INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Jobs

Dynamically adding/removing threads in a pool, and waiting for busy ones?
2

Dynamically adding/removing threads in a pool, and waiting for busy ones?

Dynamically adding/removing threads in a pool, and waiting for busy ones?

(OP)
I'm building a database thread pool, the pool has a property for thread count. By default this is 0 so there's no threads until this is set. The property reads the list count directly, so I don't store anything like "FThreadCount: Integer". So, the property setter needs to be responsible for adding/removing threads as necessary.

The adding threads part is easy, but removing them becomes tricky because I cannot kill a thread which is busy. So, when this needs to remove threads, it goes into a loop with a timeout and checks each thread's busy status. For each thread it finds not busy, it removes it, repeatedly until the count is down to the desired value.

My problem is I'm afraid to even try this, and before I try to run it (which I'm far from being able to run anyway), is this a good plan?

CODE

procedure TDBThreadPool.SetThreadCount(const Value: Integer);
const
  WAIT_TIMEOUT = 10; //Seconds to wait for available threads
var
  L: TList; //Locked thread list
  T: TDBThread; //Current thread
  D: Integer; //Difference in count
  X, Y: Integer; //Iterators
begin
  L:= LockThreads; //Acquire a locked list of threads
  try
    if (Value > L.Count) then begin
      //Add new threads
      D:= Value - L.Count;
      for X := 1 to D do begin
        T:= TDBThread.Create(Self);
        L.Add(T);
      end;
    end else
    if (Value < L.Count) then begin
      //Remove threads
      //Wait for their current processes, if any
      D:= L.Count - Value;
      for X := 1 to WAIT_TIMEOUT * 10 do begin
        for Y := L.Count - 1 downto 0 do begin
          T:= TDBThread(L[Y]);
          if not T.Busy then begin //"Busy" is true when thread is processing something
            T.Free;
          end;
          if L.Count = Value then Break;
        end;
        if L.Count = Value then Break;
        Sleep(100); (Sleep for 1/10 of a second
      end;
    end;
  finally
    UnlockThreads;
  end;
end; 

JD Solutions

RE: Dynamically adding/removing threads in a pool, and waiting for busy ones?

This is an interesting question, and one I've pursued myself in another way (scalable multi-processing for quicksort). I got it working well to start, but couldn't figure out how to schedule and restart my threads in order to keep them busy throughout the whole sort. I really have no time to look back into it any further at the moment, but just will say that I hope you find your answer, as I would like to know the answer to this too.

It is not possible for anyone to acknowledge truth when their salary depends on them not doing it.

RE: Dynamically adding/removing threads in a pool, and waiting for busy ones?

(OP)
Please bear in mind that as mentioned, I have not even tried to run (or even compile) this yet, and yes there are problems such as I'm not removing the free'd thread from the list... It's the concept that I'm aiming for though.

JD Solutions

RE: Dynamically adding/removing threads in a pool, and waiting for busy ones?

(OP)
It could be as simple as "feeding the thread a poison" as someone told me once in the past, but that would require unmanaged threads, I need to carefully manage the existence of each one, up until its time of destruction. The way I'm moving, I can't depend on feeding it a poison command and hoping that it terminates its self in a decent amount of time. If all the threads are busy with a huge process, I'd like to know about it. If the timeout expires, and there's more threads remaining than desired, shall it raise an exception? If I don't implement the timeout, what if a thread never stops? I might have to go back to the poison method.

JD Solutions

RE: Dynamically adding/removing threads in a pool, and waiting for busy ones?

2
@Jerry,

don't use sleep to wait for your threads to finish, use events:

CODE

//public var in thread:
FEvent : THandle; // or name it Busy if you want :)

//at thread construction:

FEvent := TEvent.Create(nil, False, True, nil);

// at the end of thread execute method:

SetEvent(FEvent);


//all you have to do now is wait for the event:

WaitForSingleObject(FEvent, 0 (or a Timeout in milliseconds)

//this way you don't need to guess when the thread has finished it's work 

when working this way it's important to set FreeOnTerminate to False or else the thread may be gone when the main threads want to check the event (and crashes)

-----------------------------------------------------
Helping people is my job...

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members!

Resources

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close