To Mutex или Not To Mutex?

Нужен ли мне мьютекс, если у меня есть только один читатель и один писатель? Читатель берет следующую команду (food.front()) из очереди и выполняет задачу на основе команды. После выполнения команды команда выдает команду. Писатель в очередь нажимает команды на очередь (food.push()).

Нужен ли мне мьютекс? Мой читатель (потребитель) выполняет только, если food.size() > 0. Я использую поток чтения и отправляю поток.

Ответ 1

Мьютекс используется в многопоточных средах. Я не вижу упоминания о потоках в вашем вопросе, поэтому я не вижу необходимости в мьютексе.

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

Что происходит, когда в очереди есть элементы, и поток читателя выскакивает из-за чего-то, когда нить писателя помещает что-то? Катастрофа! С помощью мьютекса вы будете уверены, что только один поток работает в очереди за раз.

Другим методом является блокировка без потоковой очереди. Он будет использовать атомарные операции, чтобы гарантировать, что данные не обрабатываются некорректно.

Ответ 2

Что произойдет, если читатель увидит, что размер больше нуля, но структура еще не полностью обновлена?

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

Ответ 3

Предполагая, что "писатель" и "читатель" находятся в отдельных потоках:

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

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

Ответ 4

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

Скажите в записи, что вы делаете ++, и читаете, что вы делаете --count и говорите, что текущее значение равно 2. Теперь обратите внимание, что эти операторы не должны быть атомарными, счетчик ++ может состоять из чтения счетчика переменных, увеличивая его, а затем записывая обратно. Никакая запись и чтение не выполняются одновременно и говорят, что выполняется первый бит записи (т.е. он загружает значение 2. тогда все чтение выполняется с уменьшением счетчика, но в другом потоке все еще было загружено значение 2, которое он увеличивает и затем записывается обратно в переменную. Теперь вы просто потеряли действие чтения.

Ответ 5

ваш вопрос зависит от двух условий:

  • существует только два потока: один - производитель, другой - потребитель
  • структура предназначена для блокировки

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