[c++] Пример для boost shared_mutex (многократное чтение / запись)?



Answers

1800 более или менее корректна, но есть несколько вопросов, которые я хотел исправить.

boost::shared_mutex _access;
void reader()
{
  boost::shared_lock< boost::shared_mutex > lock(_access);
  // do work here, without anyone having exclusive access
}

void conditional_writer()
{
  boost::upgrade_lock< boost::shared_mutex > lock(_access);
  // do work here, without anyone having exclusive access

  if (something) {
    boost::upgrade_to_unique_lock< boost::shared_mutex > uniqueLock(lock);
    // do work here, but now you have exclusive access
  }

  // do more work here, without anyone having exclusive access
}

void unconditional_writer()
{
  boost::unique_lock< boost::shared_mutex > lock(_access);
  // do work here, with exclusive access
}

Также обратите внимание, что в отличие от shared_lock, только один поток может приобретать update_lock за один раз, даже если он не обновлен (что, по моему мнению, было неудобным, когда я столкнулся с ним). Итак, если все ваши читатели являются условными писателями, вам нужно найти другое решение.

Question

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

Я думаю, что это то, что должен делать boost::shared_mutex , но я не понимаю, как его использовать, и не нашел ясного примера.

У кого-нибудь есть простой пример, который я мог бы использовать для начала?




Великий ответ Джима Морриса, я наткнулся на это, и мне потребовалось некоторое время, чтобы понять. Вот простой код, который показывает, что после отправки «запроса» для boost_lock boost (версия 1.54) блокируются все запросы shared_lock. Это очень интересно, поскольку мне кажется, что выбор между unique_lock и upgradeable_lock позволяет, если мы хотим, чтобы приоритет записи был приоритет или нет приоритета.

Также (1) в сообщении Джима Морриса, похоже, противоречит этому: Boost shared_lock. Читайте предпочитаете?

#include <iostream>
#include <boost/thread.hpp>

using namespace std;

typedef boost::shared_mutex Lock;
typedef boost::unique_lock< Lock > UniqueLock;
typedef boost::shared_lock< Lock > SharedLock;

Lock tempLock;

void main2() {
    cout << "10" << endl;
    UniqueLock lock2(tempLock); // (2) queue for a unique lock
    cout << "11" << endl;
    boost::this_thread::sleep(boost::posix_time::seconds(1));
    lock2.unlock();
}

void main() {
    cout << "1" << endl;
    SharedLock lock1(tempLock); // (1) aquire a shared lock
    cout << "2" << endl;
    boost::thread tempThread(main2);
    cout << "3" << endl;
    boost::this_thread::sleep(boost::posix_time::seconds(3));
    cout << "4" << endl;
    SharedLock lock3(tempLock); // (3) try getting antoher shared lock, deadlock here
    cout << "5" << endl;
    lock1.unlock();
    lock3.unlock();
}



Чтобы добавить еще некоторую эмпирическую информацию, я изучал всю проблему обновляемых замков и пример для повышения shared_mutex (несколько чтений / одна запись)? является хорошим ответом на добавление важной информации, что только один поток может иметь upgrade_lock, даже если он не обновлен, что важно, поскольку это означает, что вы не можете выполнить обновление с общей блокировки до уникальной блокировки, не отпуская сначала общий замок. (Это обсуждалось в другом месте, но наиболее интересная тема здесь http://thread.gmane.org/gmane.comp.lib.boost.devel/214394 )

Однако я нашел важную (недокументированную) разницу между потоком, ожидающим обновления до блокировки (т. Е. Должен ждать, пока все читатели выпустят разделяемую блокировку), и блокировку записи, ожидающую того же самого (т.е. unique_lock).

  1. Поток, ожидающий уникального_блока на shared_mutex, блокирует появление новых читателей, им приходится ждать, пока запрос авторов. Это позволяет читателям не голодать писателям (однако я считаю, что писатели могут голодать читатели).

  2. Нить, ожидающая обновления upgradeable_lock для обновления, позволяет другим потокам получать общую блокировку, поэтому этот поток может быть истощен, если читатели очень часты.

Это важный вопрос для рассмотрения и, вероятно, должен быть документирован.




Related