c ++ 11 — использование условной переменной при обнаружении события в C ++ Скотта Мейерса

Я читаю об условных переменных в книге «Эффективное современное С ++» Скотта Мейерса, ниже приводится текст.

std::condition_variable   cv
std::mutex                m

T1 (detecting task)

...
cv.notify_one();T2 (reacting task)

...
{
std::unique_lock<std::mutex> lk(m);
cv.wait(lk);

...
}

Здесь автор упоминает как ниже

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

По тексту выше у меня есть трудности в понимании

  1. Что автор подразумевает под «двумя задачами, которые будут мешать друг другу через программную логику»?

  2. Что автор имеет в виду, что нет необходимости в мьютексе?

3

Решение

Mutex используются для решения гоночных условий, например:

Состояние гонки возникает, когда два или более потоков могут получить доступ к общим данным, и они пытаются изменить их одновременно

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

Также учтите, что большинство проблем возникает, когда у вас есть «check-then-act» (например, «check», если значение равно X, тогда «act» делает что-то, что зависит от значения, являющегося X), и другой поток делает что-то со значением между «чеком» и «актом».

2

Другие решения

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

«Программная логика» относится к потоку управления программой. Я немного переформатирую код:

Data shared_data;

std::condition_variable cv;
std::mutex m;

void detecting_task()
{
initialise(shared_data);
cv.notify_one();
}

void reacting_task()
{
{
std::unique_lock<std::mutex> lk(m);
cv.wait(lk);
}
process(shared_data);
}

Даже если оба detecting_task а также reacting_task начать в то же время, вы можете видеть, что они не могут действовать на shared_data одновременно. Логика программы такова, что detecting_task только касается данных до cv уведомлен, и reacting_task только касается данных после cv уведомлен. Таким образом, они не могут перекрываться и, следовательно, не нуждаются в защите shared_data мьютексом

2

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

С учетом контекста кажется, что описывается простая система передачи сообщений, то есть вещь, использующая мьютекс и переменную условия, которая выполняет всю необходимую синхронизацию: «обнаруживающий поток» что-то замечает и отправляет уведомление через систему передачи сообщений в «реагирующая нить». Единственной вещью, которую они разделяют, является объект передачи сообщений.

1

Я не до конца понимаю цитату. Если вы не защищаете общие данные, мьютекс не нужен для доступа к памяти, наверняка. Это может означать, что задача обнаружения не потребует блокировки мьютекса.

Но, C ++ 11 condition_variable требуется мьютекс для работы. И это потому, что, по крайней мере, некоторые базовые реализации ОС требуют мьютекса, такого как pthreads

Увидеть : Почему функции условных переменных в pthreads требуют мьютекса?

0
По вопросам рекламы [email protected]