1 // c++11-style thread pool
2 // Copyright (C) 2013 Tim Blechmann
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; see the file COPYING. If not, write to
16 // the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 // Boston, MA 02111-1307, USA.
19 #ifndef THREAD_POOL_HPP
20 #define THREAD_POOL_HPP
22 #include <condition_variable>
34 virtual void run() = 0;
41 typedef std::packaged_task
<T()> work
;
43 explicit task (work
&& rhs
):
44 packaged_task(std::move(rhs
))
52 std::packaged_task
<T()> packaged_task
;
55 // LATER: implement some work-stealing
59 thread_pool(size_t thread_count
):
62 for (size_t i
= 0; i
!= thread_count
; ++i
)
63 worker_threads
.emplace_back(std::bind(&thread_pool::worker_thread
, this));
69 condition
.notify_all();
72 std::shared_ptr
<task_base
> work
;
74 std::unique_lock
<std::mutex
> lock(queue_guard
);
78 work
= std::move(tasks
.front());
84 for (auto & thread
: worker_threads
)
88 template<class Functor
>
89 auto schedule(Functor f
) -> std::future
<decltype( f() )>
91 typedef decltype(f()) T
;
93 if (worker_threads
.empty())
94 return std::async(std::launch::async
, f
);
96 std::packaged_task
<T()> job(f
);
97 std::future
<T
> ret
= job
.get_future();
100 std::unique_lock
<std::mutex
> lock(queue_guard
);
101 std::shared_ptr
<task_base
> task_ptr (new task
<T
>(std::move(job
)));
102 tasks
.emplace_back(task_ptr
);
105 condition
.notify_one();
113 std::shared_ptr
<task_base
> work
;
115 std::unique_lock
<std::mutex
> lock(queue_guard
);
116 while(!request_stop
&& tasks
.empty())
117 condition
.wait(lock
);
119 if (request_stop
&& tasks
.empty())
122 work
= std::move(tasks
.front());
129 std::vector
< std::thread
> worker_threads
;
130 std::deque
< std::shared_ptr
<task_base
> > tasks
;
132 std::mutex queue_guard
;
133 std::condition_variable condition
;
139 using detail::thread_pool
;
143 #endif // THREAD_POOL_HPP