#include <iostream>
#include <thread>
#include <condition_variable>
#include <chrono>
#include <atomic>
using namespace std;
using namespace std::chrono;
int main()
{
auto worker = [](mutex& m,
atomic<bool>& done,
atomic<bool>& main_done,
condition_variable& notify_main,
condition_variable& wait_main,
uint32_t workload)
{
unique_lock<mutex> ul(m);
while (true)
{
while (main_done == false)
wait_main.wait(ul, [&]{ return main_done.load(); });
this_thread::sleep_for(milliseconds(workload));
done.store(true);
cout << this_thread::get_id() << " job done." << endl;
notify_main.notify_one();
}
};
//----------------------------------------------------------------------
mutex main_m1, main_m2;
condition_variable cv, cv1, cv2;
atomic<bool> job1_done(false), job2_done(false), main_job(false);
thread th1(worker, std::ref(main_m1), std::ref(job1_done),
std::ref(main_job), std::ref(cv1), std::ref(cv), 300);
thread th2(worker, std::ref(main_m2), std::ref(job2_done),
std::ref(main_job), std::ref(cv2), std::ref(cv), 400);
th1.detach();
th2.detach();
//----------------------------------------------------------------------
mutex m1, m2;
unique_lock<mutex> ul1(m1), ul2(m2);
high_resolution_clock::time_point p = high_resolution_clock::now();
while (true)
{
main_job = true;
cv.notify_all();
this_thread::sleep_for(milliseconds(100));
cout << "main job done." << endl;
while (job1_done == false || job2_done == false)
{
cv1.wait(ul1, [&]{ return job1_done.load(); });
cv2.wait(ul2, [&]{ return job2_done.load(); });
}
job2_done = false;
job1_done = false;
main_job = false;
double dur = duration_cast<milliseconds>(high_resolution_clock::now() - p).count();
p = high_resolution_clock::now();
cout << dur << endl;
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dGhyZWFkPgojaW5jbHVkZSA8Y29uZGl0aW9uX3ZhcmlhYmxlPgojaW5jbHVkZSA8Y2hyb25vPgojaW5jbHVkZSA8YXRvbWljPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKdXNpbmcgbmFtZXNwYWNlIHN0ZDo6Y2hyb25vOwoKaW50IG1haW4oKSAKewogIGF1dG8gd29ya2VyID0gW10obXV0ZXgmIG0sCiAgICAgICAgICAgICAgICAgICBhdG9taWM8Ym9vbD4mIGRvbmUsCiAgICAgICAgICAgICAgICAgICBhdG9taWM8Ym9vbD4mIG1haW5fZG9uZSwKICAgICAgICAgICAgICAgICAgIGNvbmRpdGlvbl92YXJpYWJsZSYgbm90aWZ5X21haW4sCiAgICAgICAgICAgICAgICAgICBjb25kaXRpb25fdmFyaWFibGUmIHdhaXRfbWFpbiwKICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IHdvcmtsb2FkKQogIHsKICAgIHVuaXF1ZV9sb2NrPG11dGV4PiB1bChtKTsKICAgIHdoaWxlICh0cnVlKQogICAgewogICAgICB3aGlsZSAobWFpbl9kb25lID09IGZhbHNlKQogICAgICAgIHdhaXRfbWFpbi53YWl0KHVsLCBbJl17IHJldHVybiBtYWluX2RvbmUubG9hZCgpOyB9KTsKCiAgICAgIHRoaXNfdGhyZWFkOjpzbGVlcF9mb3IobWlsbGlzZWNvbmRzKHdvcmtsb2FkKSk7CiAgICAgIGRvbmUuc3RvcmUodHJ1ZSk7CiAgICAgIGNvdXQgPDwgdGhpc190aHJlYWQ6OmdldF9pZCgpIDw8ICIgam9iIGRvbmUuIiA8PCBlbmRsOwoKICAgICAgbm90aWZ5X21haW4ubm90aWZ5X29uZSgpOwogICAgfQogIH07CgogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICBtdXRleCBtYWluX20xLCBtYWluX20yOwogIGNvbmRpdGlvbl92YXJpYWJsZSBjdiwgY3YxLCBjdjI7CiAgYXRvbWljPGJvb2w+IGpvYjFfZG9uZShmYWxzZSksIGpvYjJfZG9uZShmYWxzZSksIG1haW5fam9iKGZhbHNlKTsKCiAgdGhyZWFkIHRoMSh3b3JrZXIsIHN0ZDo6cmVmKG1haW5fbTEpLCBzdGQ6OnJlZihqb2IxX2RvbmUpLCAKICAgICAgICAgICAgIHN0ZDo6cmVmKG1haW5fam9iKSwgc3RkOjpyZWYoY3YxKSwgc3RkOjpyZWYoY3YpLCAzMDApOwogIHRocmVhZCB0aDIod29ya2VyLCBzdGQ6OnJlZihtYWluX20yKSwgc3RkOjpyZWYoam9iMl9kb25lKSwgCiAgICAgICAgICAgICBzdGQ6OnJlZihtYWluX2pvYiksIHN0ZDo6cmVmKGN2MiksIHN0ZDo6cmVmKGN2KSwgNDAwKTsKCiAgdGgxLmRldGFjaCgpOwogIHRoMi5kZXRhY2goKTsKCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIG11dGV4IG0xLCBtMjsKICB1bmlxdWVfbG9jazxtdXRleD4gdWwxKG0xKSwgdWwyKG0yKTsKICBoaWdoX3Jlc29sdXRpb25fY2xvY2s6OnRpbWVfcG9pbnQgcCA9IGhpZ2hfcmVzb2x1dGlvbl9jbG9jazo6bm93KCk7CgogIHdoaWxlICh0cnVlKQogIHsKICAgIG1haW5fam9iID0gdHJ1ZTsKICAgIGN2Lm5vdGlmeV9hbGwoKTsKCiAgICB0aGlzX3RocmVhZDo6c2xlZXBfZm9yKG1pbGxpc2Vjb25kcygxMDApKTsKICAgIGNvdXQgPDwgIm1haW4gam9iIGRvbmUuIiA8PCBlbmRsOwoKICAgIHdoaWxlIChqb2IxX2RvbmUgPT0gZmFsc2UgfHwgam9iMl9kb25lID09IGZhbHNlKQogICAgewogICAgICBjdjEud2FpdCh1bDEsIFsmXXsgcmV0dXJuIGpvYjFfZG9uZS5sb2FkKCk7IH0pOwogICAgICBjdjIud2FpdCh1bDIsIFsmXXsgcmV0dXJuIGpvYjJfZG9uZS5sb2FkKCk7IH0pOwogICAgfQoKICAgIGpvYjJfZG9uZSA9IGZhbHNlOwogICAgam9iMV9kb25lID0gZmFsc2U7CiAgICBtYWluX2pvYiA9IGZhbHNlOwoKICAgIGRvdWJsZSBkdXIgPSBkdXJhdGlvbl9jYXN0PG1pbGxpc2Vjb25kcz4oaGlnaF9yZXNvbHV0aW9uX2Nsb2NrOjpub3coKSAtIHApLmNvdW50KCk7CiAgICBwID0gaGlnaF9yZXNvbHV0aW9uX2Nsb2NrOjpub3coKTsKICAgIGNvdXQgPDwgZHVyIDw8IGVuZGw7CiAgfQoKCXJldHVybiAwOwp9