Last active
June 17, 2019 20:36
-
-
Save carlchen0928/e3f24dadae3df7cdb806 to your computer and use it in GitHub Desktop.
Simple thread pool. Don't support user wait all task done.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "join_threads.h" | |
#include "threadsafe_subtle_queue.cpp" | |
#include "threadsafe_exceptionsafe_queue.cpp" | |
#include <thread> | |
#include <vector> | |
#include <atomic> | |
/* | |
* Simplest thread pool implementation, exception safe. | |
* Don't support user wait all task finish. | |
* It will never stop if everything goes will. | |
*/ | |
class simple_threadpool | |
{ | |
public: | |
explicit simple_threadpool() | |
: _done(false), _joiner(_threads) | |
{ | |
int n = std::thread::hardware_concurrency(); | |
try | |
{ | |
// printf("creating threads...\n"); | |
for (int i = 0; i < n; i++) | |
{ | |
_threads.push_back( | |
std::thread(&simple_threadpool::work, this)); | |
} | |
// printf("threads created.\n"); | |
} | |
catch (...) | |
{ | |
// When exception happend, send signal to stop all | |
// sub threads. Than _joiner will wait all threads | |
// than have been created. | |
_done = true; | |
throw; | |
} | |
} | |
~simple_threadpool() | |
{ | |
// Must be called before data member's dtor. | |
_done = true; | |
} | |
template <class funciontype> | |
void submit(funciontype f) | |
{ | |
// printf("pushing f...\n"); | |
_work_queue.push(std::function<void()>(f)); | |
} | |
private: | |
/* | |
* Variables must be declaration as fowllowing sequence. | |
* When dtor, _done and _work_queue should dtor after _threads | |
* because we can not dtor _work_queue until all threads stop. | |
* The same as _joiner and _threads. | |
*/ | |
std::atomic_bool _done; | |
// threadsafe_exceptionsafe_queue<std::function<void()> > _work_queue; | |
threadsafe_subtle_queue<std::function<void()> > _work_queue; | |
std::vector<std::thread> _threads; | |
// when dtor, _done must be set to true. | |
// all child threads are closing. | |
join_threads _joiner; // RAII for thread, dtor call join | |
void work() | |
{ | |
while (!_done) | |
{ | |
std::function<void()> task; | |
if (_work_queue.try_pop(task)) | |
{ | |
// printf("starting execute function\n"); | |
task(); | |
// printf("executing function done!\n"); | |
} | |
else | |
{ | |
// printf("empyt queue...\n"); | |
std::this_thread::yield(); | |
} | |
} | |
} | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <thread> | |
#include <vector> | |
class join_threads | |
{ | |
public: | |
explicit join_threads(std::vector<std::thread>& threads) | |
: _threads(threads) | |
{} | |
~join_threads() | |
{ | |
for (int i = 0; i < _threads.size(); ++i) | |
{ | |
if (_threads[i].joinable()) | |
{ | |
_threads[i].join(); | |
} | |
} | |
} | |
private: | |
// Must be a reference. | |
// Thread object can not be shared. | |
// Copy ctor and copy assignment declared privatly. | |
// But we can use move to transfer thread object. | |
std::vector<std::thread>& _threads; | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "simple_threadpool.cpp" | |
#include <stdio.h> | |
#include <thread> | |
#include <iostream> | |
#include <memory> | |
// #include "threadsafe_subtle_queue.cpp" | |
void func() | |
{ | |
printf("thread %d called\n", std::this_thread::get_id()); | |
// printf("hahah\n"); | |
} | |
int main() | |
{ | |
simple_threadpool pool; | |
for (int i = 0; i < 20; i++) | |
pool.submit(func); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment