Thread
pools & Executors
Run your concurrent code in a performant way
How do I
use the thread pools?
Wangle provides two concrete thread pools as well as
building them in as part of a complete async framework. Generally, you might
want to grab the global executor, and use it with a future, like this:
auto f =
someFutureFunction().via(getCPUExecutor()).then(...)
Or maybe you need to construct a thrift/memcache client, and
need an event base:
auto f =
getClient(getIOExecutor()->getEventBase())->callSomeFunction(args...)
.via(getCPUExecutor())
.then([](Result r){ .... do something with result});
vs. C++11's std::launch
The current C++11 std::launch only has two modes: async or
deferred. In a production system, neither is what you want: async will launch a
new thread for every launch without limit, while deferred will defer the work
until it is needed lazily, but then do the work in the current thread
synchronously when it is needed.
Wangle's thread pools always launch work as soon as
possible, have limits to the maximum number of tasks / threads allowed, so we
will never use more threads than absolutely needed.
Why do we need yet another set of thread pools?
Unfortunately none of the existing thread pools had every
feature needed - things based on pipes are too slow. Several older ones didn't
support std::function.
Why do we need several different types of thread
pools?
If you want epoll support, you need an fd - event_fd is the
latest notification hotness. Unfortunately, an active fd triggers all the epoll
loops it is in, leading to thundering herd - so if you want a fair queue you
need to use some kind of semaphore. Unfortunately semaphores can't be put in
epoll loops, so they are incompatible with IO. Fortunately, you usually want to
separate the IO and CPU bound work anyway to give stronger tail latency
guarantees on IO.
IOThreadPoolExecutor
CPUThreadPoolExecutor
ThreadPoolExecutor
Base class that contains the thread startup/shutdown/stats
logic
Observers
An observer interface is provided to listen for thread
start/stop events. This is useful to create objects that should be
one-per-thread. If threads are added/removed from the thread pool it also have
them work correctly.
Stats
PoolStats are provided to get task count, running time, etc.
Name | Views | Likes |
---|---|---|
FOLLY: Benefits | 100 | 1 |
FOLLY: synchronization/Rcu.h | 214 | 1 |
FOLLY: Synchronized.h (3) | 154 | 1 |
FOLLY: Synchronized.h (2) | 178 | 1 |
FOLLY: Synchronized.h (1) | 213 | 1 |
FOLLY: dynamic.h | 274 | 1 |
FOLLY: Benchmark.h | 126 | 1 |
FOLLY: stats/Histogram.h | 160 | 1 |
FOLLY: PackedSyncPtr.h | 106 | 1 |
FOLLY: ProducerConsumerQueue.h | 175 | 1 |
FOLLY: SmallLocks.h | 91 | 1 |
FOLLY: ThreadCachedInt.h (2) | 92 | 1 |
FOLLY: ThreadCachedInt.h (1) | 92 | 1 |
FOLLY: ThreadLocal.h | 127 | 1 |
FOLLY: small_vector.h | 240 | 1 |
FOLLY: GroupVarint.h | 114 | 1 |
FOLLY: Function.h | 179 | 1 |
FOLLY: Format.h | 155 | 1 |
FOLLY: FBVector | 172 | 1 |
FOLLY: FBString | 106 | 1 |
FOLLY: Thread pools & Executors | 104 | 1 |
FOLLY: DynamicConverter | 87 | 1 |
FOLLY: AtomicHashMap | 128 | 1 |
FOLLY: Components | 114 | 1 |
FOLLY: Overview | 164 | 1 |
Comments