David Blume's GitList
Repositories
testcode.git
Code
Commits
Branches
Tags
Search
Tree:
9d5b420
Branches
Tags
c++11
main
start
testcode.git
product
deadlock
deadlock.cpp
Added a routine to cause a deadlock. See http://wiki.dlma.com/gdb for more.
David Blume
commited
9d5b420
at 2016-10-16 20:24:34
deadlock.cpp
Blame
History
Raw
#include <iostream> #include <string> #include <vector> #include <thread> #include <mutex> #include <unistd.h> #include <random> #include <chrono> #include "deadlock.hpp" using namespace std; namespace { std::mutex left_chopstick; std::mutex right_chopstick; std::vector<std::thread> workers; void do_work_on_right(bool, int32_t); int get_rnd() { static std::random_device rd; static std::mt19937 gen(rd()); static std::uniform_int_distribution<> dis(100, 200); return dis(gen); } void do_work_on_left(bool have_right, int32_t tick) { std::lock_guard<std::mutex> lm (left_chopstick); std::this_thread::sleep_for(std::chrono::milliseconds(get_rnd())); if (have_right) { std::cout << "deadlock::thread " << std::hex << this_thread::get_id() << " " << tick << endl; } else { do_work_on_right(true, tick); } } void do_work_on_right(bool have_left, int32_t tick) { std::lock_guard<std::mutex> rm (right_chopstick); std::this_thread::sleep_for(std::chrono::milliseconds(get_rnd())); if (have_left) { std::cout << "deadlock::thread " << std::hex << this_thread::get_id() << " " << tick << endl; } else { do_work_on_left(true, tick); } } void work(int32_t ticks) { for(int32_t tick = ticks; tick >= 0; tick--) { do_work_on_right(false, tick); } } }; int deadlock() { uint32_t ticks = 10; cout << "The function " << __PRETTY_FUNCTION__ << " was called." << endl; cerr << "WARNING: Expect a deadlock. See http://wiki.dlma.com/gdb" << endl; // Construct the thread right into the push_back() call. workers.push_back(std::thread([=]{ for(uint32_t tick = 0; tick <= ticks; tick++) { do_work_on_left(false, tick); // usleep(get_rnd() * 1000); // u for microseconds } })); // Or, move the thread into the array. std::thread t2(work, ticks); workers.push_back(move(t2)); // Don't return before the other threads have finished. for (auto &w : workers) { if (w.joinable()) w.join(); } return 0; }