c++ - readers-/writers multithreading in C++11 -


i'm trying implement readers writers solution in c++ std::thread.

i create several reader-threads run in infinite loop, pausing time in between each read access. tried recreate algorithm presented in tanenbaum's book of operating systems:

    rc_mtx.lock(); // lock incrementing readcount     read_count += 1;     if (read_count == 1) // if first reader         db_mtx.lock(); // make lock on database     rc_mtx.unlock();      cell_value = data_base[cell_number]; // read data database     rc_mtx.lock();     read_count -= 1; // when finished 'sign reader off'     if (read_count == 0) // if last 1         db_mtx.unlock(); // release lock on database mutex     rc_mtx.unlock(); 

of course, problem thread might satisfy condition of being last reader (and therefore want unlock) has never acquired db_mtx. tried open 'mother' thread readers take care of acquiring , releasing mutex, go lost during process. if there elegant way overcome issue (thread might try release mutex has never been acquired) in elegant way i'd love hear!

you can use condition variable pause writers if readers in progress, instead of using separate lock.

// --- read code rw_mtx.lock();    // block if there write in progress read_count += 1;  // announce intention read rw_mtx.unlock(); cell_value = data_base[cell_number]; rw_mtx.lock(); read_count -= 1;  // announce intention read if (read_count == 0) rw_write_q.notify_one(); rw_mtx.unlock();  // --- write code std::unique_lock<std::mutex> rw_lock(rw_mtx); write_count += 1; rw_write_q.wait(rw_lock, []{return read_count == 0;}); data_base[cell_number] = cell_value; write_count -= 1; if (write_count > 0) rw_write_q.notify_one(); 

this implementation has fairness issue, because new readers can cut in front of waiting writers. fair implementation involve proper queue allow new readers wait behind waiting writers, , new writers wait behind waiting readers.

in c++14, can use shared_timed_mutex instead of mutex achieve multiple readers/single writer access.

// --- read code std::shared_lock<std::shared_timed_mutex> read_lock(rw_mtx); cell_value = data_base[cell_number];  // --- write code std::unique_lock<std::shared_timed_mutex> write_lock(rw_mtx); data_base[cell_number] = cell_value; 

there plain shared_mutex implementation in next c++ standard (probably c++17).