Разработать синхронизационный объект (rwlock), позволяющий одновременное чтение данных несколькими потоками, но разрешающий запись данных только одному потоку.
Разработать набор классов:
Примерные интерфейсы классов (публичные методы).
class rwlock {
public:
rwlock();
rwlock(const rwlock&) = delete;
rwlock(rwlock&&);
rwlock& operator=(const rwlock&) = delete;
rwlock& operator=(rwlock&&);
~rwlock();
bool read_lock(int64_t timeOut = -1); // попытка захвата объекта на чтение
void read_unlock(); // освобождение объекта
bool write_lock(int64_t timeOut = -1); // попытка захвата объекта на запись
void write_unlock(); // освобождение объекта
}
rwlock()
конструкторrwlock(const rwlock&) = delete;
- удалённый конструктор копированияrwlock(rwlock&&);
- move конструкторrwlock& operator=(const rwlock&) = delete;
- удалённый оператор =rwlock& operator=(rwlock&&);
- оператор =~rwlock();
bool read_lock(int64_t timeOut = -1);
- попытка захвата объекта на чтение. Если объект не захвачен на запись, осуществляет захват на чтение. На чтение разрешается захватывать 'много' раз. Если объект захвачен на запись, осуществляет ожидание в течении timeOut (мс) и пытается захватить объект.
void read_unlock();
- освобождение ридера
bool write_lock(int64_t timeOut = -1);
- попытка захвата объекта на запись. Если объект не захвачен на запись и не захвачен на чтение, осуществляет захват на запись. На запись разрешается захватывать только один раз. Если объект захвачен на запись или чтение, осуществляет ожидание в течении timeOut (мс) и пытается захватить объект.
void write_unlock();
// освобождение объекта
class reader_lock {
public:
reader_lock() = delete;
reader_lock(const rwlock&) = delete;
reader_lock(rwlock&&) = delete;
reader_lock& operator=(const rwlock&) = delete;
reader_lock& operator=(rwlock&&) = delete;
reader_lock(rwlock& parent, bool auto = true, int64_t timeout = -1);
~reader_lock();
bool is_locked();
bool lock(int64_t timeout = -1);
void unlock();
}
reader_lock() = delete;
reader_lock(const rwlock&) = delete;
reader_lock(rwlock&&) = delete;
reader_lock& operator=(const rwlock&) = delete;
reader_lock& operator=(rwlock&&) = delete;
reader_lock(rwlock& parent, bool auto = true, int64_t timeout = -1);
- конструктор. Параметры: rwlock& parent
- ссылка на основной объект, bool auto = true
- захватывать автоматически, в конструкторе, int64_t timeout = -1
- время ожитания
~reader_lock();
- деструктор. Если захвачен, освобождает основной объект (чтение)
bool is_locked();
- возвращает флаг - захвачен, не захвачен.
bool lock(int64_t timeout = -1);
- попытка захвата объекта на чтение. Возврашает флаг успешности.
void unlock();
- освобождение чтения.
Замечание : lock
/unlock
- разрешается вызывать много раз, но кол-во вызовов unlock
должно соответствовать кол-ву вызовов lock
, включая начальный (в конструкторе).
class writer_lock {
public:
writer_lock() = delete;
writer_lock(const rwlock&) = delete;
writer_lock(rwlock&&) = delete;
writer_lock& operator=(const rwlock&) = delete;
writer_lock& operator=(rwlock&&) = delete;
writer_lock(rwlock& parent, bool auto = true, int64_t timeout = -1);
~writer_lock();
bool is_locked();
bool lock(int64_t timeout = -1);
void unlock();
}
writer_lock() = delete;
writer_lock(const rwlock&) = delete;
writer_lock(rwlock&&) = delete;
writer_lock& operator=(const rwlock&) = delete;
writer_lock& operator=(rwlock&&) = delete;
writer_lock(rwlock& parent, bool auto = true, int64_t timeout = -1);
- конструктор. Параметры: rwlock& parent
- ссылка на основной объект, bool auto = true
- захватывать автоматически, в конструкторе, int64_t timeout = -1
- время ожитания
~writer_lock();
- деструктор. Если захвачен, освобождает основной объект (запись)
bool is_locked();
- возвращает флаг - захвачен, не захвачен.
bool lock(int64_t timeout = -1);
- попытка захвата объекта на запись. Возврашает флаг успешности.
void unlock();
- освобождение записи.
Замечание : lock
/unlock
- разрешается вызывать много раз, но кол-во вызовов unlock
должно соответствовать кол-ву вызовов lock
, включая начальный (в конструкторе).