Created
September 3, 2017 16:26
-
-
Save e673/31b73495bfb83e818f226d2300568176 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 <thread> | |
#include <condition_variable> | |
#include <mutex> | |
#include <atomic> | |
#include <stdio.h> | |
#include <vector> | |
#include <chrono> | |
std::condition_variable worker_start, worker_complete; | |
std::mutex worker_mutex, master_mutex; | |
std::atomic<int> scheduled_task; | |
std::atomic<int> completed_count; | |
std::atomic<long long> count; | |
const int N = 1; | |
int wait_for_task(int prev_task) | |
{ | |
int task = scheduled_task.load(); | |
if (task != prev_task) | |
return task; | |
std::unique_lock<std::mutex> locker(worker_mutex); | |
while (true) | |
{ | |
task = scheduled_task.load(); | |
if (task != prev_task) | |
return task; | |
worker_start.wait(locker); | |
} | |
} | |
void notify_task_completed() | |
{ | |
if (--completed_count == 0) | |
{ | |
std::unique_lock<std::mutex> locker(master_mutex); | |
worker_complete.notify_one(); | |
} | |
} | |
void worker() | |
{ | |
int prev_task = 0; | |
while (true) | |
{ | |
prev_task = wait_for_task(prev_task); | |
// process task | |
notify_task_completed(); | |
} | |
} | |
void schedule_task(int task) | |
{ | |
completed_count.store(N); | |
scheduled_task.store(task); | |
std::unique_lock<std::mutex> locker(worker_mutex); | |
worker_start.notify_all(); | |
} | |
void wait_for_completion() | |
{ | |
if (completed_count.load() == 0) | |
return; | |
std::unique_lock<std::mutex> locker(master_mutex); | |
while (completed_count.load() != 0) | |
worker_complete.wait(locker); | |
} | |
void worker2() | |
{ | |
int i = 0; | |
while (true) | |
{ | |
schedule_task(++i); | |
wait_for_completion(); | |
count++; | |
} | |
} | |
int main(int argc, char **argv) | |
{ | |
std::vector<std::thread> workers; | |
std::thread thr_master(&worker2); | |
for (int i = 0; i < N; i++) | |
workers.emplace_back(&worker); | |
std::this_thread::sleep_for(std::chrono::seconds(1)); | |
printf("N = %d, Count = %ld\n", N, count.load()); | |
getchar(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment