Created
November 18, 2018 21:57
-
-
Save NorimasaNabeta/f39059e83466e0a12c999a6319d428ab to your computer and use it in GitHub Desktop.
This file contains 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 <iostream> | |
#include <vector> | |
#include <string> | |
#include <chrono> | |
#include <queue> | |
#include <functional> | |
#include <thread> | |
#include <mutex> | |
//#include <atomic> | |
#include <condition_variable> | |
class task { | |
public: | |
int state; | |
std::function<void(task&)> proc; | |
task(): state(0){} ; | |
virtual ~task() {}; | |
}; | |
class threadpool { | |
private: | |
bool running; | |
std::mutex init_mutex; | |
//std::queue<std::function<void(void)>> work_queue; | |
std::queue<task> work_queue; | |
std::mutex mutex; | |
std::condition_variable cv; | |
std::vector<std::thread> threads; | |
public: | |
threadpool(size_t num_threads = std::thread::hardware_concurrency()) | |
: running(true) { | |
auto thread_loop = [&](size_t id) { | |
while (running) { | |
std::unique_lock<std::mutex> lk(mutex); | |
cv.wait(lk, [&]{return (!work_queue.empty());}); | |
std::cout << "[" << id << "] queue: " << work_queue.size() << std::endl; | |
if( !work_queue.empty() ) { | |
auto work = work_queue.front(); | |
work_queue.pop(); | |
mutex.unlock(); | |
work.proc( work ); | |
cv.notify_all(); | |
} | |
else { // for sprious | |
mutex.unlock(); | |
} | |
}}; | |
threads.reserve(num_threads); | |
for (size_t i = 0; i < num_threads; i++) { | |
threads.push_back(std::thread(thread_loop, i)); | |
} | |
}; | |
virtual ~threadpool(){ | |
std::cout << "exit queue: " << work_queue.size() << std::endl; | |
running = false; | |
for (std::thread& t : threads) { | |
t.join(); | |
} | |
}; | |
//void add_work(std::function<void(void)> work){ | |
void add_work(std::function<void(task&)> work){ | |
std::lock_guard<std::mutex> lk(mutex); | |
task task_tmp; | |
task_tmp.proc = work; | |
///work_queue.push(work); | |
work_queue.push(task_tmp); | |
cv.notify_all(); | |
}; | |
void clear_work(){ | |
// std::packaged_task | |
// std::queue<std::function<void(void)>> empty; | |
std::queue<task> empty; | |
std::lock_guard<std::mutex> lk(mutex); | |
std::swap(work_queue, empty); | |
}; | |
void wait(){ | |
std::unique_lock<std::mutex> lk(mutex); | |
std::cout << "wait_queue: " << work_queue.size() << std::endl; | |
cv.wait(lk, [&]{return (work_queue.empty());}); | |
}; | |
}; | |
int virtual_machine( std::vector<std::string> cl, int seq=0 ) | |
{ | |
const std::string trap("TRAP"); | |
const std::string syncg("SYNCG"); | |
const std::string actst("ACTST"); | |
for (; seq<cl.size(); ++seq ){ | |
if ( cl[seq].compare(trap) == 0 ){ | |
std::cout << cl[seq] << std::endl; | |
throw 999; | |
} | |
else if ( cl[seq].compare(syncg) == 0 ){ | |
return seq; | |
} | |
else if ( cl[seq].compare(actst) == 0 ){ | |
return seq; | |
} | |
else { | |
std::cout << cl[seq] << "..." << std::endl; | |
std::this_thread::sleep_for(std::chrono::milliseconds(20)); | |
} | |
} | |
return -1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment