Thread pools & Executors
Thread pools & Executors
Run your concurrent code in a performant way
All about thread pools #
How do I use the thread pools? #
Wangle provides two concrete thread pools (IOThreadPoolExecutor, CPUThreadPoolExecutor) 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. See implementation details below about each type of executor.
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 (one queue total vs. one queue per worker thread), 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 #
- Uses event_fd for notification, and waking an epoll loop.
- There is one queue (NotificationQueue specifically) per thread/epoll.
- If the thread is already running and not waiting on epoll, we don't make any additional syscalls to wake up the loop, just put the new task in the queue.
- If any thread has been waiting for more than a few seconds, its stack is madvised away. Currently however tasks are scheduled round robin on the queues, so unless there is no work going on, this isn't very effective.
- ::getEventBase() will return an EventBase you can schedule IO work on directly, chosen round-robin.
- Since there is one queue per thread, there is hardly any contention on the queues - so a simple spinlock around an std::deque is used for the tasks. There is no max queue size.
- By default, there is one thread per core - it usually doesn't make sense to have more IO threads than this, assuming they don't block.
CPUThreadPoolExecutor #
- A single queue backed by folly/LifoSem and folly/MPMC queue. Since there is only a single queue, contention can be quite high, since all the worker threads and all the producer threads hit the same queue. MPMC queue excels in this situation. MPMC queue dictates a max queue size.
- LifoSem wakes up threads in Lifo order - i.e. there are only few threads as necessary running, and we always try to reuse the same few threads for better cache locality.
- Inactive threads have their stack madvised away. This works quite well in combination with Lifosem - it almost doesn't matter if more threads than are necessary are specified at startup.
- stop() will finish all outstanding tasks at exit
- Supports priorities - priorities are implemented as multiple queues - each worker thread checks the highest priority queue first. Threads themselves don't have priorities set, so a series of long running low priority tasks could still hog all the threads. (at last check pthreads thread priorities didn't work very well)
ThreadPoolExecutor #
Base class that contains the thread startup/shutdown/stats logic, since this is pretty disjoint from how tasks are actually run
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, but also have them work correctly if threads are added/removed from the thread pool.
Stats #
PoolStats are provided to get task count, running time, waiting time, etc.
Thread pools & Executors的更多相关文章
- Java theory and practice: Thread pools and work queues--reference
Why thread pools? Many server applications, such as Web servers, database servers, file servers, or ...
- java 多线程--- Thread Runnable Executors
java 实现多线程的整理: Thread实现多线程的两种方式: (1)继承 Thread类,同时重载 run 方法: class PrimeThread extends Thread { long ...
- 小规模的流处理框架.Part 1: thread pools
原文链接:http://ifeve.com/part-1-thread-pools/ 很不错的一篇文章
- Thread Pools
许多程序会动态创建数十个设置上百个线程.举个例子,一个web服务器可能在每一个新到来的请求时创建一个新线程,然后在请求完成后将其终止. 然而,创建一个新线程将会带来一定的耗费:它需要在内核中创建自身必 ...
- java thread reuse(good)
I have always read that creating threads is expensive. I also know that you cannot rerun a thread. I ...
- 【转】Java 并发:Executors 和线程池
原文地址: http://baptiste-wicht.com/posts/2010/09/java-concurrency-part-7-executors-and-thread-pools.htm ...
- The threads in the thread pool will process the requests on the connections concurrently.
https://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html Most of the executor implem ...
- The CLR's Thread Pool
We were unable to locate this content in zh-cn. Here is the same content in en-us. .NET The CLR's Th ...
- Effective Java 73 Avoid thread groups
Thread groups were originally envisioned as a mechanism for isolating applets for security purposes. ...
随机推荐
- WIN7不能上网
http://zhidao.baidu.com/link?url=lYL0Sti_nX3JDz3pA3cVh49nyYDEQBJ6P5fxwB4La0FurHlgmWGMdgfMGjQSWxj17sH ...
- mybatis环境搭建和开发步骤
环境搭建 第一步:导入jar包 第二步:导入核心配置文件(mybatis-config.xml) <?xml version="1.0" encoding="UTF ...
- moment时间转换插件
在vue中的使用: import moment = from “moment” Vue.prototype.$moment = moment; 获取时间戳 : var res = this.$mome ...
- linux下修改了tomcat端口之后无法访问
查看防火墙,是否将修改之后的端口加入防火墙规则内,如没有,加入规则内,重启防火墙,如果还是无法访问,请看第二步 执行bin目录下shutdown.sh脚本,如果正常关闭,则执行startup.sh脚本 ...
- 浅谈Eclipse调用Tomcat服务的原理
浅谈Eclipse调用Tomcat服务的原理 转:http://www.thinksaas.cn/group/topic/341645/ 转:http://www.173it.cn/Html/?581 ...
- spring @Autowired注入的原理
只知道如何用Autowired注解,知道可以替代set,get方法,很方便,却一直不知道,为什么可以代替 今天探索一下原因,所谓知其然还要知其所以然,才能理解的更好,记忆的更牢,才能转化为自己的知识. ...
- Uoj 441 保卫王国
Uoj 441 保卫王国 动态 \(dp\) .今天才来写这个题. 设 \(f[u][0/1]\) 表示子树 \(u\) 中不选/选 \(u\) 时的最小权值和,显然有:\(f[u][0]=\sum ...
- bzoj 4811 由乃的OJ
bzoj 4811 由乃的OJ 考虑树链剖分. 树剖后用一颗线段树维护一段连续区间,类似于一个函数,各位上进入 \(0/1\) ,输出的数字分别是什么.注意到最多只有 \(64\) 位,可以用一个 \ ...
- BZOJ4237 稻草人 【CDQ分治】
Description JOI村有一片荒地,上面竖着N个稻草人,村民们每年多次在稻草人们的周围举行祭典. 有一次,JOI村的村长听到了稻草人们的启示,计划在荒地中开垦一片田地.和启示中的一样,田地需要 ...
- vs2010中配置OpenGL以及针对64位系统所遇问题的解决办法
一.下面将对VS2010中配置OpenGL进行简单介绍. 学习OpenGL前的准备工作 第一步,选择一个编译环境 现在Windows系统的主流编译环境有Visual Studio,Broland C+ ...