Created
July 22, 2014 22:21
-
-
Save gicmo/5bdc09cbcd51e0b9cd64 to your computer and use it in GitHub Desktop.
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
// Created by Christian Kellner on 22/07/2014. | |
// Copyright (c) 2014 G-Node. All rights reserved. | |
// | |
#include <iostream> | |
#include <thread> | |
#include <vector> | |
#include <mutex> | |
#include <utility> | |
class threadpool { | |
public: | |
threadpool(size_t poolsize) | |
: fun(nullptr), shutdown(false) { | |
for (size_t i = 0; i < poolsize; i++) { | |
threads.emplace_back(runloop, std::ref(*this), i); | |
} | |
} | |
~threadpool() { | |
{ | |
//not really neccessary, but whhhyyyy nooooot | |
std::unique_lock<std::mutex> lock(guard); | |
shutdown = true; | |
} | |
cond.notify_all(); | |
for (auto& t: threads) { | |
t.join(); | |
} | |
std::cerr << "TP destoryed" << std::endl; | |
} | |
void launch(size_t n, std::function<void(size_t)> &&f) { | |
//assign function | |
{ | |
std::unique_lock<std::mutex> lock(guard); | |
fun = std::forward<std::function<void(size_t)>>(f); | |
worksize = n; | |
workitem = 0; | |
} | |
cond.notify_all(); | |
{ | |
std::unique_lock<std::mutex> lock(guard); | |
cond.wait(lock, [this]{ return !(workitem < worksize); }); | |
//when we are arrive here, all work should be done | |
} | |
} | |
private: | |
static void runloop(threadpool &pool, size_t id) { | |
std::unique_lock<std::mutex> lock(pool.guard); | |
while (1) { | |
pool.cond.wait(lock, [&pool]{ | |
return pool.shutdown || pool.workitem < pool.worksize; | |
}); | |
if (pool.shutdown) { | |
return; | |
} | |
size_t workid = -1; | |
while (pool.workitem < pool.worksize) { | |
workid = pool.workitem++; | |
lock.unlock(); | |
pool.fun(workid); | |
lock.lock(); | |
} | |
//we hold the mutex here | |
if (workid + 1 == pool.worksize) { | |
pool.cond.notify_one(); | |
} | |
} | |
} | |
std::vector<std::thread> threads; | |
std::function<void(size_t)> fun; | |
std::mutex guard; | |
std::condition_variable cond; | |
size_t worksize; | |
size_t workitem; | |
bool shutdown; | |
}; | |
int main(int argc, const char * argv[]) { | |
std::mutex lock; | |
{ | |
threadpool pool(8); | |
std::mutex *lptr = &lock; | |
pool.launch(4, [lptr](size_t id) { | |
lptr->lock(); | |
std::cout << "W" << id << std::endl; | |
std::cout.flush(); | |
lptr->unlock(); | |
}); | |
} | |
std::chrono::milliseconds dura( 2000 ); | |
std::this_thread::sleep_for( dura ); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment