В чем разница между" мьютексом "и"замком"?
Я очень смущен разницей между блокировкой и мьютексом. В Boost docs говорится:
Типы Блокировки
- шаблон класса lock_guard
- шаблон класса unique_lock
- шаблон класса shared_lock
- класс шаблон upgrade_lock
- шаблон класса upgrade_to_unique_lock
- специфичный для мьютекса класс scoped_try_lock
мьютекс Типы
- мьютекс класс
- Typedef try_mutex
- timed_mutex класс
- recursive_mutex класс
- typedef для recursive_try_mutex
- recursive_timed_mutex класс
- shared_mutex класс
в другой статье я вижу такие функции,
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
}
обновлены вопросы
- может ли кто-нибудь предложить некоторые разъяснения между " мьютексом" а "замок"?
- надо создать shared_lock на shared_mutex? Что произойдет, если я создам unique_lock на shared_mutex?
- или если я создам shared_lock на мьютекс, это означает, что мьютекс может не делиться между несколькими потоками?
3 ответов
A мьютекс объект синхронизации. Вы получаете блокировку мьютекса в начале раздела кода и освобождаете его в конце, чтобы гарантировать, что никакой другой поток не обращается к тем же данным одновременно. Мьютекс обычно имеет время жизни, равное времени жизни защищаемых данных, и доступ к одному мьютексу осуществляется несколькими потоками.
A заблокировать объект - это объект, который инкапсулирует этот замок. Когда объект построен, он получает блокировку мьютекса. Когда он разрушен, замок отпущен. Обычно для каждого доступа к общим данным создается новый объект блокировки.
мьютекс-это объект, который может быть заблокирована. Блокировка-это объект, который поддерживает замок. Чтобы создать блокировку, нужно передать ей мьютекс.
блокировки могут обеспечить взаимное исключение, но не синхронизацию условий.В отличие от семафора, замок имеет владельца, а владение играет важную роль роль в поведении блокировки
пример
class lockableObject { public void F() {
mutex.lock(); ...; mutex.unlock();
}
public void G() {
mutex.lock(); ...; F(); ...; mutex.unlock();
}
private mutexLock mutex; }
// method G() calls method F()
мьютекс блокировки в классе lockableObject используется для преобразования методов F() и G () в критические разделы. Таким образом, только один поток за раз может выполняться внутри метода lockableObject. Когда поток вызывает метод G(), мьютекс заблокирован. Когда метод G() вызывает метод F (), mutex.lock () выполняется в F (), но вызывающий поток не блокируется, так как он уже владеет мьютексом. Если бы мьютекс был двоичным семафором вместо блокировки, вызов из G() В F () блокировал бы вызывающий поток при мьютексе.P () было выполнено в F (). (Напомним, что сочетания операций P() и V() на двоичном семафоре должны чередоваться.) Это создаст тупик, так как никакие другие потоки не смогут выполняться внутри F() или G().
Это различия между блокировками и двоичным кодом семафоры: 1 для двоичного семафора, если два вызова сделаны toP () без какого-либо промежуточного вызова V (), второй вызов будет блокировать. Но поток, который владеет блокировкой и снова запрашивает владение, не блокируется. (Остерегайтесь того факта, что блокировки не всегда рекурсивны, поэтому проверьте документацию перед использованием блокировки.) 2 владелец для последовательных вызовов lock() и unlock () должен быть одним и тем же потоком. Но последовательные вызовы P () и V () могут выполняться разными потоками.