Skip to content

Instantly share code, notes, and snippets.

@pqviet07
Last active April 12, 2023 07:26
Show Gist options
  • Save pqviet07/eb53b1021def5287c0c3ba33bfb4fd4e to your computer and use it in GitHub Desktop.
Save pqviet07/eb53b1021def5287c0c3ba33bfb4fd4e to your computer and use it in GitHub Desktop.
RWLock in c++11 và c++17
#include <iostream>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <vector>
class ReadWriteLock {
public:
void read(std::function<void()> reader) {
std::unique_lock<std::mutex> lock(mutex_);
read_cv_.wait(lock, [this] { return num_writers_ == 0; });
++num_readers_;
lock.unlock();
reader();
lock.lock();
--num_readers_;
if (num_readers_ == 0) {
write_cv_.notify_one();
}
}
void write(std::function<void()> writer) {
std::unique_lock<std::mutex> lock(mutex_);
++num_writers_;
write_cv_.wait(lock, [this] { return num_readers_ == 0 && !writer_active_; });
writer_active_ = true;
writer();
writer_active_ = false;
--num_writers_;
if (num_writers_ == 0) {
read_cv_.notify_all();
} else {
write_cv_.notify_one();
}
}
private:
std::mutex mutex_;
std::condition_variable read_cv_;
std::condition_variable write_cv_;
int num_readers_ = 0;
int num_writers_ = 0;
bool writer_active_ = false;
};
void reader_function(ReadWriteLock& rw_lock, int reader_id) {
rw_lock.read([reader_id] {
std::cout << "Reader " << reader_id << " is reading." << std::endl;
});
}
void writer_function(ReadWriteLock& rw_lock, int writer_id) {
rw_lock.write([writer_id] {
std::cout << "Writer " << writer_id << " is writing." << std::endl;
});
}
int main() {
ReadWriteLock rw_lock;
std::vector<std::thread> readers;
std::vector<std::thread> writers;
for (int i = 0; i < 5; ++i) {
readers.emplace_back(reader_function, std::ref(rw_lock), i);
writers.emplace_back(writer_function, std::ref(rw_lock), i);
}
for (auto& reader : readers) {
reader.join();
}
for (auto& writer : writers) {
writer.join();
}
return 0;
}
#include <iostream>
#include <shared_mutex>
#include <mutex>
#include <thread>
#include <vector>
class ReadWriteLock {
public:
void read(std::function<void()> reader) {
std::shared_lock<std::shared_mutex> lock(rw_mutex_);
reader();
}
void write(std::function<void()> writer) {
std::unique_lock<std::shared_mutex> lock(rw_mutex_);
writer();
}
private:
std::shared_mutex rw_mutex_;
};
void reader_function(ReadWriteLock& rw_lock, int reader_id) {
rw_lock.read([reader_id] {
std::cout << "Reader " << reader_id << " is reading." << std::endl;
});
}
void writer_function(ReadWriteLock& rw_lock, int writer_id) {
rw_lock.write([writer_id] {
std::cout << "Writer " << writer_id << " is writing." << std::endl;
});
}
int main() {
ReadWriteLock rw_lock;
std::vector<std::thread> readers;
std::vector<std::thread> writers;
for (int i = 0; i < 5; ++i) {
readers.emplace_back(reader_function, std::ref(rw_lock), i);
writers.emplace_back(writer_function, std::ref(rw_lock), i);
}
for (auto& reader : readers) {
reader.join();
}
for (auto& writer : writers) {
writer.join();
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment