Last active
April 12, 2023 07:26
-
-
Save pqviet07/eb53b1021def5287c0c3ba33bfb4fd4e to your computer and use it in GitHub Desktop.
RWLock in c++11 và c++17
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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