djechlin
djechlin

Reputation: 60768

Design pattern for threadpooling

I currently have an application that has a large number of threads and this makes the application very large. Each thread is long-running, basically an infinite loop of polling for new emails then handling them. Each thread holds on to one SSL connection, which is why threading works well for the application.

I want to use thread pooling. The simplest approach is to just fix the number of threads then add say 10 users per thread but even at that point it does not seem to be balancing the work as uniformly as 1 user / thread as each loop is fairly long to process. Plus this isn't actually a thread pool.

My question is - what is the proper design pattern here (as it's certainly more intelligent than what I wrote above), and is there a C++ library that handles this well? It would also be helpful to point me to a Java utility as in my experience it's pretty easy to work out a design pattern from a Java utility.

Upvotes: 3

Views: 3515

Answers (5)

duffymo
duffymo

Reputation: 308763

I'd put a BlockingDeque in between with a thread pooled consumer on the back end. That decouples the email producers from the consumers and allows you to pool up the consumers on the back end. Have a look at this:

Producer Consumer Example

Upvotes: 1

RalphChapin
RalphChapin

Reputation: 3158

One user/thread is probably a good starting point. Anything that blocks or can be blocked needs to run in its own thread to avoid holding up or being held up by other executing code. If the actual processing of an e-mail is going to run straight through, it can be placed in a "runnable", to use the Java term, and submitted to a thread pool. The Java term would be ThreadPoolExecutor, and it can't be that hard to write a simple one yourself. You'd want one thread for each likely CPU core to get the most work from your computer.

If the work per e-mail is not that great, it might be simpler and faster to skip the thread pool and just do the work on the reader thread. You've paid the cost to run it, you may as well get all the work out of it you can.

At the other extreme, if processing an e-mail involves blocking or getting blocked, you may want to fire up a new thread for each e-mail. You can end up with a lot of threads, but it will get the maximum amount of work out of your computer. You don't want to be falling behind on your e-mails with your CPU usage at only 5%.

Upvotes: 3

Tanner Sansbury
Tanner Sansbury

Reputation: 51881

There are numerous patterns that could solve the problem, but the key point in making the decision is understanding the pattern's consequences. The ACE website has some papers for some concurrency patterns that may be suitable, such as Active Object, Proactor, and Reactor. The examples are C++, but there are diagrams and descriptions that will be helpful if you pursue your own implementation.

The proactor may provide an elegant solution or serve as the foundation for another pattern. For C++ implementations, I would recommend the boost::asio library:

  • Fairly well documented and examples.
  • SSL support.
  • The HTTP Server 3 example shows how to use boost::asio with a thread pool.

If you do not want a dependency on boost, then the asio library is also packaged separately here. For more patterns and information, consider this book.

Upvotes: 1

Yair Zaslavsky
Yair Zaslavsky

Reputation: 4137

Look at commons ThreadPool. Altough Java - it's open source, you can look at the code and easily port to C++

Upvotes: 0

PermanentGuest
PermanentGuest

Reputation: 5331

I didn't really understand your statement "does not seem to be balancing the work as uniformly as 1 user / thread as each loop is fairly long to process".

In any case, the Active Object pattern could be an elegant one in your case. This is a combination of 6 other patterns. In effect, this achieves a thread pool with nicely abstracted entities.

Upvotes: 0

Related Questions