Skip to content

Instantly share code, notes, and snippets.

@nguditi
Created April 12, 2023 03:15
Show Gist options
  • Save nguditi/247971bef5b4363c8d7206c2093ecff2 to your computer and use it in GitHub Desktop.
Save nguditi/247971bef5b4363c8d7206c2093ecff2 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
class SharedMutex {
public:
void lock_shared() {
std::unique_lock<std::mutex> lock(m_mutex);
m_readers_waiting++;
m_read_cv.wait(lock, [this](){ return m_writers_waiting == 0; });
m_readers_waiting--;
m_readers++;
}
void unlock_shared() {
std::unique_lock<std::mutex> lock(m_mutex);
m_readers--;
if (m_readers == 0 && m_writers_waiting > 0) {
m_write_cv.notify_one();
}
}
void lock() {
std::unique_lock<std::mutex> lock(m_mutex);
m_writers_waiting++;
m_write_cv.wait(lock, [this](){ return m_readers == 0 && !m_writing; });
m_writers_waiting--;
m_writing = true;
}
void unlock() {
std::unique_lock<std::mutex> lock(m_mutex);
m_writing = false;
if (m_readers_waiting > 0) {
m_read_cv.notify_all();
} else {
m_write_cv.notify_one();
}
}
private:
std::mutex m_mutex;
std::condition_variable m_read_cv;
std::condition_variable m_write_cv;
int m_readers = 0;
int m_writers_waiting = 0;
int m_readers_waiting = 0;
bool m_writing = false;
};
SharedMutex mutex;
void read_data() {
// Read shared data under shared lock
mutex.lock_shared();
std::cout << "Reading data" << std::endl;
// ... Read shared data ...
mutex.unlock_shared();
}
void write_data() {
// Write exclusive data under unique lock
mutex.lock();
std::cout << "Writing data" << std::endl;
// ... Write exclusive data ...
mutex.unlock();
}
int main() {
// Create two threads, one for reading and one for writing
std::thread reader(read_data);
std::thread writer(write_data);
// Wait for threads to finish
reader.join();
writer.join();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment