Created
January 10, 2016 14:58
-
-
Save yinchunxiang/a8136948475c3877eb73 to your computer and use it in GitHub Desktop.
C++ ThreadPool
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
class ThreadPool { | |
public: | |
ThreadPool(int num_threads) : stop_(0) { | |
for (int i = 0; i < num_threads; ++i) { | |
threads_.push_back(std::thread(&ThreadPool::run, this)); | |
} | |
} | |
void AddTask(const std::function<void()> &task) { | |
{ | |
std::unique_lock<std::mutex> lock(mutex_); | |
queue_.push(task); | |
} | |
cond_.notify_one(); | |
} | |
~ThreadPool() { | |
stop(); | |
} | |
private: | |
std::vector<std::thread> threads_; | |
void run() { | |
std::cout << "start " << std::this_thread::get_id() << endl; | |
while (!stop_) { | |
std::function<void()> task; | |
{ | |
std::unique_lock<std::mutex> lock(mutex_); | |
if (queue_.empty()) { | |
std::cout << "queue is empty" << endl; | |
cond_.wait(lock); | |
} | |
///被唤醒可能是因为有任务了 | |
///也可能是要退出了,所以要先判断下是否退出 | |
if (stop_) { | |
std::cout << "stop thread" << std::endl; | |
break; | |
} | |
///有可能析构的时候queue里还有任务 | |
///导致都被唤醒 | |
//if (!queue_.empty()) { | |
task = std::move(queue_.front()); | |
queue_.pop(); | |
//} | |
} | |
task(); | |
} | |
std::cout << "end " << std::this_thread::get_id() << endl; | |
return; | |
} | |
void stop() { | |
{ | |
std::unique_lock<std::mutex> lock(mutex_); | |
stop_ = 1; | |
} | |
cond_.notify_all(); | |
for (auto &thread : threads_) { | |
thread.join(); | |
} | |
} | |
std::queue<std::function<void()>> queue_; | |
std::mutex mutex_; | |
std::condition_variable cond_; | |
int stop_; | |
}; | |
int main(int argc, const char *argv[]) | |
{ | |
std::function<void()> f1 = [](){ std::cout << "f1" << std::endl;}; | |
std::function<void()> f2 = [](){ std::cout << "f2" << std::endl;}; | |
std::function<void()> f3 = [](){ std::cout << "f3" << std::endl;}; | |
ThreadPool tp(2); | |
tp.AddTask(f1); | |
sleep(1); | |
std::cout << "sleep 1 ." << std::endl; | |
tp.AddTask(f2); | |
std::cout << "sleep 2 ." << std::endl; | |
tp.AddTask(f3); | |
sleep(10); | |
return 0; | |
} |
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
class ThreadPool { | |
public: | |
ThreadPool(int num_threads) : stop_(0) { | |
for (int i = 0; i < num_threads; ++i) { | |
threads_.push_back(std::thread(&ThreadPool::run, this)); | |
} | |
} | |
void AddTask(const std::function<void()> &task) { | |
{ | |
std::unique_lock<std::mutex> lock(mutex_); | |
queue_.push(task); | |
} | |
cond_.notify_one(); | |
} | |
~ThreadPool() { | |
stop(); | |
} | |
private: | |
std::vector<std::thread> threads_; | |
void run() { | |
std::cout << "start " << std::this_thread::get_id() << endl; | |
while (!stop_) { | |
std::function<void()> task; | |
{ | |
std::unique_lock<std::mutex> lock(mutex_); | |
if (queue_.empty()) { | |
std::cout << "queue is empty" << endl; | |
cond_.wait(lock); | |
} | |
///被唤醒可能是因为有任务了 | |
///也可能是要退出了,所以要先判断下是否退出 | |
if (stop_) { | |
std::cout << "stop thread" << std::endl; | |
break; | |
} | |
///有可能析构的时候queue里还有任务 | |
///导致都被唤醒 | |
//if (!queue_.empty()) { | |
task = std::move(queue_.front()); | |
queue_.pop(); | |
//} | |
} | |
task(); | |
} | |
std::cout << "end " << std::this_thread::get_id() << endl; | |
return; | |
} | |
void stop() { | |
{ | |
std::unique_lock<std::mutex> lock(mutex_); | |
stop_ = 1; | |
} | |
cond_.notify_all(); | |
for (auto &thread : threads_) { | |
thread.join(); | |
} | |
} | |
std::queue<std::function<void()>> queue_; | |
std::mutex mutex_; | |
std::condition_variable cond_; | |
int stop_; | |
}; | |
int main(int argc, const char *argv[]) | |
{ | |
std::function<void()> f1 = [](){ std::cout << "f1" << std::endl;}; | |
std::function<void()> f2 = [](){ std::cout << "f2" << std::endl;}; | |
std::function<void()> f3 = [](){ std::cout << "f3" << std::endl;}; | |
ThreadPool tp(2); | |
tp.AddTask(f1); | |
sleep(1); | |
std::cout << "sleep 1 ." << std::endl; | |
tp.AddTask(f2); | |
std::cout << "sleep 2 ." << std::endl; | |
tp.AddTask(f3); | |
sleep(10); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment