vak: (Знайка)
[personal profile] vak
Тип Mutex<T> хорош, но разрешает доступ нескольким потокам только по очереди. Что если нам чаще требуется только читать объект, а изменять только изредка? Через RwLock<T> можно получить множественный доступ на чтение.

Question: Please show a meaningful C++ implementation of type RwLock<T>.

I'll create a C++ implementation of RwLock<T> similar to Rust's RwLock, which provides a reader-writer lock allowing multiple readers or one writer. We'll use C++'s std::shared_mutex (available since C++17) as the underlying synchronization primitive.

Here's the implementation: rwlock.cpp.
#include <shared_mutex>
#include <memory>

template<typename T>
class RwLock {
private:
T data;
mutable std::shared_mutex mtx; // mutable to allow locking in const methods

public:
// Constructor
explicit RwLock(T value) : data(std::move(value)) {}

// Read guard class (multiple readers allowed)
class ReadGuard {
private:
const T& data_ref;
std::shared_lock<std::shared_mutex> lock;

public:
ReadGuard(const T& d, std::shared_mutex& m)
: data_ref(d), lock(m) {}

const T& operator*() const { return data_ref; }
const T* operator->() const { return &data_ref; }
};

// Write guard class (exclusive writer)
class WriteGuard {
private:
T& data_ref;
std::unique_lock<std::shared_mutex> lock;

public:
WriteGuard(T& d, std::shared_mutex& m)
: data_ref(d), lock(m) {}

T& operator*() { return data_ref; }
T* operator->() { return &data_ref; }
};

// Lock methods
ReadGuard read_lock() const {
return ReadGuard(data, mtx);
}

WriteGuard write_lock() {
return WriteGuard(data, mtx);
}

// Prevent copying
RwLock(const RwLock&) = delete;
RwLock& operator=(const RwLock&) = delete;

// Allow move construction
RwLock(RwLock&&) = default;
RwLock& operator=(RwLock&&) = default;
};
Key components and features:

1. RwLock<T> Class:
  • Uses std::shared_mutex for reader-writer locking
  • Stores the data of type T
  • Marked as mutable to allow read locking in const methods
2. ReadGuard Class:
  • Uses std::shared_lock for shared access
  • Provides read-only access to the data
  • Multiple ReadGuards can exist simultaneously
3. WriteGuard Class:
  • Uses std::unique_lock for exclusive access
  • Provides read-write access to the data
  • Only one WriteGuard can exist at a time
4. Interface:
  • read_lock(): Returns a ReadGuard for reading
  • write_lock(): Returns a WriteGuard for writing
  • Both guards automatically unlock when they go out of scope (RAII)
5. Differences from Rust's RwLock:
  • C++ doesn't have Rust's poisoning mechanism
  • No Result/Option return types (Rust uses these for lock acquisition)
  • Relies on C++ RAII instead of Rust's ownership system
The example demonstrates:
  • Multiple readers can access the data simultaneously
  • Writers get exclusive access
  • Automatic cleanup when guards go out of scope
  • Thread-safe concurrent access
Possible extensions could include:
  • Try-lock variants (try_read_lock, try_write_lock)
  • Timeout-based locking
  • Upgradeable read locks
  • Condition variable support
This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at [email protected]

OSZAR »