Вы неправильно понимаете, как обычно используются мьютексы.
Если вы хотите выполнить какую-то работу, вы приобретаете мьютекс, чтобы выяснить, какую работу вам нужно выполнить.Вы делаете это, потому что «какая работа вам нужна» распределяется между потоком, который решает, какую работу нужно выполнить, и потоком, который будет выполнять эту работу.Но затем вы освобождаете мьютекс, который защищает «какую работу вам нужно делать», пока вы выполняете работу.
Затем, когда вы заканчиваете работу, вы получаете мьютекс, который защищает ваш отчет о том, что работа выполнена.Это необходимо, потому что статус работы передается другим потокам.Вы устанавливаете этот статус на «выполнено», а затем освобождаете мьютекс.
Обратите внимание, что ни один поток не удерживает мьютекс очень долго, только за микроскопические доли секунды, которые он должен проверить или изменить общее состояние.Таким образом, чтобы увидеть, завершена ли работа, вы можете получить мьютекс, который защищает отчеты о состоянии этой работы, проверить статус и затем освободить мьютекс.Поток, выполняющий работу, не будет удерживать этот мьютекс дольше, чем крошечные доли секунды, он должен изменить этот статус.
Если вы держите мьютексы так долго, что вам вообще не нужно ждать, пока онибыть освобожденным, вы либо делаете что-то не так, либо используете мьютексы очень нетипичным способом.
Так что используйте мьютекс для защиты статуса работы.Если вам нужно дождаться окончания работы, также используйте переменную условия.Удерживайте этот мьютекс только при изменении или проверке статуса работы.
Но, если поток пытается получить уже полученный мьютекс, этот поток будет вынужден ждать, пока поток, который изначальноПриобретенный мьютекс освобождает его.Таким образом, пока этот поток ожидает, может ли он быть на самом деле пригодным для использования.Вот где мой вопрос.
Если вы рассматриваете любой случай, когда один поток может замедлить другой поток для «ожидания», то вы никогда не сможете избежать ожидания.Все, что должно произойти, это то, что один поток обращается к памяти, и это может замедлить работу другого потока.Так что вы делаете, никогда не обращаетесь к памяти?
Когда мы говорим о том, что один поток «ожидает» другого, мы имеем в виду ожидание того, что поток выполнит реальную работу.Мы не беспокоимся о микроскопических издержках синхронизации между потоками, потому что мы ничего не можем с этим поделать, и потому что это ничтожно мало.
Если вы в буквальном смысле хотите найти способ, которым один поток никогда не сможет, никогда не замедлитсяВ другом потоке вам придется переделать практически все, для чего мы используем потоки.
Обновление:
Например, рассмотрим некоторый код с мьютексом и логическим значением.Логическое значение указывает, выполнена ли работа.Процесс «назначить работу» выглядит следующим образом:
- Создайте рабочий объект с мьютексом и логическим значением.Установите для логического значения значение false.
- Отправьте поток для работы с этим объектом.
Поток "do work" выглядит следующим образом:
- DoРабота.(Мьютекс здесь не удерживается.)
- Получить мьютекс.
- Установить логическое значение true.
- Отменить мьютекс.
""работа выполнена "поток выглядит следующим образом:
- получение мьютекса.
- копирование логического значения.
- освобождение мьютекса.
- просмотр скопированного значения.
Это позволяет одному потоку выполнять работу, а другому потоку проверять, выполняется ли работа в любое время, когда она этого захочет, при выполнении других задач.Единственный случай, когда один поток ожидает другого, - это случай «один на миллион», когда поток, который должен проверить, выполнена ли работа, выполняет проверку в тот момент, когда работа только что завершилась.Даже в этом случае он обычно блокируется менее чем на микросекунду, так как потоку, который содержит мьютекс, нужно только установить один логический тип и освободить мьютекс.И даже если это вас беспокоит, большинство мьютексов имеют неблокирующую функцию «попытаться заблокировать» (которую вы использовали бы в потоке «проверьте, если работа выполнена», чтобы поток проверки никогда не блокировался).
И это нормальный способ использования мьютексов.Фактическое утверждение - исключение, а не правило.