Атомная загрузка и хранение с памятью упорядочены - PullRequest
0 голосов
/ 13 сентября 2018

Везде, где я читаю, я вижу сильные рекомендации не использовать ослабленный порядок памяти, мне интересно, является ли следующий фрагмент кода одним из исключений, в которых это будет работать, или есть какие-то последствия, которых я не вижу.

class SessionHolder {
public:

  void set_session(std::shared_ptr<Session> session) {
    std::atomic_store_explicit(&_session, session, std::memory_order_relaxed);
  }

  std::shared_ptr<Session> get_session() const {
    return std::atomic_load_explicit(&_session, std::memory_order_relaxed);
  }

private:

  std::shared_ptr<Session> _session;
};

В принципе, когда я делаю get_session, мне все равно, какой сеанс я получаю, если это сеанс или nullptr.Но если другой поток хранит данные (что случается редко), я бы хотел получить это значение в разумные сроки.

  • Как я понимаю, даже не гарантируется, что я получу это значениепросто я получу значение, которое хранилось там в какой-то момент времени, но я всегда мог получить nullptr.
  • На практике, кажется, работает, могу ли я ожидать, что оно завершится ошибкой (всегда получая nullptr) в некоторыхситуации / платформу конкретно?
  • Можно ли настроить порядок памяти в операции хранилища только для того, чтобы это исправить?Например, memory_order_release будет распространять изменения в другой поток?

Дополнительные сведения о том, как используется этот класс:

По сути, у меня есть какой-то видпоток, который непрерывно производит данные.В определенный момент клиентский процесс может подключиться (запустить сеанс) и начать прослушивание этих данных.Поток производителя непрерывно записывает в поток, если нет активного сеанса, данные отбрасываются, иначе отправляются клиенту.Другой поток, в определенный момент (не часто), когда клиент подключается, достигает этого потока и устанавливает сеанс.

Поток производителя должен иметь как можно меньше конфликтов, даже если это означает пропуск нескольких сообщений.

1 Ответ

0 голосов
/ 13 сентября 2018

Как я понимаю, даже не гарантируется, что я получу это значение, просто я получу значение, которое хранилось там в определенный момент времени, но я всегда мог получить nullptr.

Да, гипотетически возможно, что каждый вызов get_session будет возвращать нулевой указатель, но маловероятно. Одна гарантия, которую предлагает даже смягченный порядок памяти, состоит в том, что, как только конкретный поток наблюдает значение, тот же поток не может впоследствии наблюдать предыдущее значение. Таким образом, как только конкретный поток начинает наблюдать ненулевой указатель, этот поток всегда будет наблюдать ненулевой указатель при последующих вызовах get_session (при условии, что нулевой указатель никогда не сохраняется).

На практике, кажется, работает, могу ли я ожидать, что он потерпит неудачу (всегда получая nullptr) в некоторых ситуациях / платформе конкретно?

Не то, чтобы я знал.

Можно ли настроить порядок памяти в операции сохранения только для того, чтобы это исправить? например memory_order_release распространит изменения на другой поток?

Нет. Стандарт не предусматривает какого-либо метода для обеспечения того, чтобы межпотоковая связь была завершена в течение какого-то определенного промежутка времени. Только реализация может предоставить такую ​​гарантию.

Последнее замечание: nullptr - это не то же самое, что «нулевой указатель». Это специальная константа уникального типа, которую можно преобразовать в нулевой указатель другого типа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...