Skip to content

Instantly share code, notes, and snippets.

@uchan-nos
Last active March 18, 2019 04:22
Show Gist options
  • Save uchan-nos/d502ae1dadb733dc3e40f39056c9183b to your computer and use it in GitHub Desktop.
Save uchan-nos/d502ae1dadb733dc3e40f39056c9183b to your computer and use it in GitHub Desktop.
Multi threading in C++17
#include <iostream>
#include <chrono>
#include <string>
#include <thread>
#include <atomic>
#include <vector>
#include <queue>
#include <mutex>
#include <condition_variable>
using namespace std::literals::chrono_literals;
std::atomic should_stop{false};
struct WorkerData {
std::queue<int> q;
std::mutex mtx;
std::condition_variable cond;
};
void WorkerFunc(WorkerData& wd, std::chrono::milliseconds sleep_duration) {
while (!should_stop) {
int data{0};
{
std::unique_lock lk{wd.mtx};
wd.cond.wait(lk, [&] { return !wd.q.empty() || should_stop; });
if (should_stop) {
break;
}
data = wd.q.front();
wd.q.pop();
}
std::cout << "Worker(" << std::this_thread::get_id() << "): "
<< "Process data " << data
<< ", and sleep " << sleep_duration.count() << " msecs"
<< std::endl;
std::this_thread::sleep_for(sleep_duration);
}
}
int main() {
std::vector<std::thread> threads;
WorkerData wd;
threads.emplace_back(WorkerFunc, std::ref(wd), 200ms);
threads.emplace_back(WorkerFunc, std::ref(wd), 70ms);
while (!std::cin.eof()) {
int data{0};
std::cin >> data;
if (data == -1) {
break;
}
{
std::lock_guard lk{wd.mtx};
wd.q.push(data);
}
wd.cond.notify_one();
}
while (true) {
{
std::lock_guard lk{wd.mtx};
if (wd.q.empty()) {
break;
}
}
std::cout << "[main thread] sleeping 1000 msec" << std::endl;
std::this_thread::sleep_for(1'000ms);
}
should_stop = true;
wd.cond.notify_all();
for (auto& t : threads) {
t.join();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment