Library tutorials & articles

Handling multiple socket read & write operations

Shutting down dormant threads

Shutting down dormant threads

Often work items come in batches, the thread pool gets busy, expands, services all of the work items and then becomes less busy. At this point the pool contains threads which aren't being used but which are still consuming resources. These dormant threads can be safely shutdown as the pool can expand again as load increases. The question is, how do we decide when to shut down some threads?

The maintenance thread that handles our blocking dispatch also handles checking for dormant threads. Every so often (a configurable amount) the maintenance thread uses an algorithm to determine if it should shut some threads down. The current algorithm is as follows:

  void CThreadPool::HandleDormantThreads()
  {
      if ((size_t)m_activeThreads > m_minThreads)
      {
        const size_t dormantThreads = m_activeThreads - m_processingThreads;
        if (dormantThreads > m_maxDormantThreads)
        {
            const size_t threadsToShutdown = (dormantThreads - m_maxDormantThreads) / 2 + 1;
            StopWorkerThreads(threadsToShutdown);
        }
      }
  }

If we have more threads than the minimum number we're allowed to have, find out how many threads aren't currently processing work items and if that number is more than the number of dormant threads that we're allowed to have, shut half of them down (rounding up). Stopping worker threads is a simple case of posting an IO completion key of 0 to the work port for each worker thread that we want to shut down.

Doing the work

We now have a thread pool that fulfills our requirements of automatic expansion and contraction depending upon load and non blocking dispatch for users. The remaining thing to do is allow the derived class to provide its own WorkerThread class to do the work. The worker thread class must implement the following interface:

  virtual bool Initialise();
  virtual void Process(
      ULONG_PTR completionKey,
      DWORD dwNumBytes,
      OVERLAPPED *pOverlapped) = 0;
  virtual void Shutdown();

Initialise() is called when it's first created, Shutdown() is called when the thread is terminating and Process() is called for each work item.

Comments

  1. 08 May 2007 at 11:15
    It's up to you. You may select anyone you want, but better except some standart ports. Read documentation.
  2. 13 Feb 2004 at 01:46

    Hi there,


    How do I find the port of the machine for scoket connection.


    Thanks


    PPCC

  3. 01 Jan 1999 at 00:00

    This thread is for discussions of Handling multiple socket read & write operations.

Leave a comment

Sign in or Join us (it's free).

Len Holgate Len has been programming for over 20 years, having first started with a Sinclair ZX-80. Now he runs his own consulting company, JetByte Limited. JetByte provides contract programming and consultanc...

Related discussion

Related podcasts

  • Listener Feedback 67

    This mailbag episode includes FASM, scripts, sockets, SSL/TLS, HTTPS, Windows 7's XP mode, and more. Security Now wiki shownotes For 16kpbs versions, transcripts, and notes (including fixes), visit Steve's site: grc.com, also the home of the best disk maintenance and recovery utility ever written...

Want to stay in touch with what's going on? Follow us on twitter!