33 Thread support library [thread]

33.4 Mutual exclusion [thread.mutex]

33.4.3 Mutex requirements [thread.mutex.requirements]

33.4.3.4 Shared mutex types [thread.sharedmutex.requirements]

Стандартные библиотеки типов shared_­mutex и shared_­timed_­mutex есть shared mutex types. Типы общих мьютексов должны соответствовать requirements of mutex typesи дополнительно должны соответствовать требованиям, изложенным ниже. В этом описании m обозначает объект общего типа мьютекса.

В дополнение к режиму монопольного владения блокировкой, указанному в [thread.mutex.requirements.mutex], общие типы мьютексов предоставляют shared lock режим владения. Несколько агентов выполнения могут одновременно владеть общей блокировкой общего типа мьютекса. Но ни один агент выполнения не должен удерживать разделяемую блокировку, в то время как другой агент выполнения удерживает монопольную блокировку того же общего типа мьютекса, и наоборот. Максимальное количество исполнительных агентов, которые могут совместно использовать общую блокировку для одного общего типа мьютекса, не указано, но должно быть не менее 10000. Если больше, чем максимальное количество исполнительных агентов пытается получить общую блокировку, избыточные исполнительные агенты должны блокировать до тех пор, пока количество разделяемых блокировок не уменьшится ниже максимального значения другими исполнительными агентами, снимающими свою общую блокировку.

Выражение m.lock_­shared() должно быть правильно сформированным и иметь следующую семантику:

Requires: Вызывающий поток не владеет мьютексом.

Effects: Блокирует вызывающий поток до тех пор, пока для вызывающего потока не будет получено совместное владение мьютексом. Если выбрасывается исключение, то для текущего потока не должна быть получена разделяемая блокировка.

Postconditions: Вызывающий поток имеет общую блокировку мьютекса.

Return type: void.

Synchronization: Предыдущие unlock() операции на одном и том же объекте являются synchronize with этой операцией.

Throws: system_­error когда требуется исключение ([thread.req.exception]).

Error conditions:

  • operation_­not_­permitted - если поток не имеет права выполнять операцию.

  • resource_­deadlock_­would_­occur - если реализация обнаруживает, что возникнет тупик.

Выражение m.unlock_­shared() должно быть правильно сформированным и иметь следующую семантику:

Requires: Вызывающий поток должен удерживать общую блокировку мьютекса.

Effects: Снимает общую блокировку мьютекса, удерживаемого вызывающим потоком.

Return type: void.

Synchronization: Эта операция является synchronizes with последующими lock() операциями, которые получают право собственности на один и тот же объект.

Throws: Ничего такого.

Выражение m.try_­lock_­shared() должно быть правильно сформированным и иметь следующую семантику:

Requires: Вызывающий поток не владеет мьютексом.

Effects: Пытается получить совместное владение мьютексом для вызывающего потока без блокировки. Если долевое владение не получено, нет эффекта и try_­lock_­shared() немедленно возвращается. Реализация может не получить блокировку, даже если она не удерживается каким-либо другим потоком.

Return type: bool.

Returns: true если была приобретена блокировка долевого владения, в false противном случае.

Synchronization: Если try_­lock_­shared() возвращается true, предыдущие unlock() операции с тем же объектом synchronize with это операция.

Throws: Ничего такого.

33.4.3.4.1 Class shared_mutex [thread.sharedmutex.class]

namespace std {
  class shared_mutex {
  public:
    shared_mutex();
    ~shared_mutex();

    shared_mutex(const shared_mutex&) = delete;
    shared_mutex& operator=(const shared_mutex&) = delete;

    // Exclusive ownership
    void lock(); // blocking
    bool try_lock();
    void unlock();

    // Shared ownership
    void lock_shared(); // blocking
    bool try_lock_shared();
    void unlock_shared();

    using native_handle_type = implementation-defined; // See [thread.req.native]
    native_handle_type native_handle();                // See [thread.req.native]
  };
}

Класс shared_­mutex предоставляет нерекурсивный мьютекс с семантикой совместного владения.

Класс shared_­mutex должен удовлетворять всем требованиям shared mutex requirements. Это должен быть класс стандартной компоновки (пункт [class]).

Поведение программы не определено, если:

  • он уничтожает shared_­mutex объект, принадлежащий любому потоку,

  • поток пытается рекурсивно получить право собственности на a shared_­mutex, или

  • поток завершается, когда ему принадлежит какое-либо право собственности на a shared_­mutex.

shared_­mutex может быть синонимом shared_­timed_­mutex.