Сам мьютекс гарантирует, что только один поток выполнения может заблокировать мьютекс в любой момент времени. Вы должны убедиться, что изменение связанной переменной происходит только тогда, когда мьютекс заблокирован.
C ++ дает вам способ сделать это немного легче, чем в чем-то вроде C. В C вы можете написать код правильно, гарантируя, что при любом изменении переменной вы сначала заблокируете мьютекс. (и, конечно, разблокируйте его, когда закончите).
В C ++ довольно просто инкапсулировать все это в класс с некоторой перегрузкой операторов:
class protected_int {
int value; // this is the value we're going to share between threads
mutex m;
public:
operator int() { return value; } // we'll assume no lock needed to read
protected_int &operator=(int new_value) {
lock(m);
value = new_value;
unlock(m);
return *this;
}
};
Очевидно, что я сильно упрощаю это (до такой степени, что это, вероятно, бесполезно в нынешнем виде), но, надеюсь, вы поймете, что большая часть кода обрабатывает объект protected_int
так, как если бы он был нормальная переменная.
Однако, когда вы это сделаете, мьютекс автоматически блокируется каждый раз, когда вы присваиваете ему значение, и сразу после этого разблокируется. Конечно, это в значительной степени простейший случай - во многих случаях вам нужно что-то сделать, например заблокировать мьютекс, изменить две (или более) переменные в унисон, а затем разблокировать. Однако, независимо от сложности, идея остается в том, что вы централизуете весь код, который выполняет модификацию, в одном месте, поэтому вам не нужно беспокоиться о блокировке мьютекса в остальной части кода. Если у вас есть две или более переменных вместе, как это, вам, как правило, придется блокировать мьютекс для чтения, а не только для записи - в противном случае вы можете легко получить неправильное значение, когда одна из переменных была изменена, а другая - нет. т.