У меня вопрос, как я могу убедиться, что только один поток использует экземпляр в определенное время.
Как правило , вы не можете.
Ответ Натана Оливера работает в особом случае, когда другие модули могут «использовать экземпляр» только путем вызова его методов. В этом случае вы можете убедиться, что каждый из этих методов блокирует один и тот же мьютекс.
Но если ваш синглтон предоставляет какой-либо элемент данных public
, все ставки отключены: у вас не будет никакого способа контролировать, как другие модули "используют" открытые элементы данных вашего объекта.
Осторожно! Даже если вы сделаете все члены данных частными и сделаете объект-одиночку действительно, действительно «поточно-ориентированным»; все же не гарантирует безопасность потоков другого кода, которая может зависеть от некоторых отношений между вашим одноэлементным объектом и некоторыми другими данными.
Безопасность потоков на самом деле не означает, что «только один поток использует объект одновременно». Потокобезопасность заключается в сохранении инвариантных отношений . Например, если у вас есть структура данных с двойным кольцом , то важным инвариантом является то, что p->next->prev
всегда должно быть равно p
.
Поток, который хочет склеить новый элемент в кольцо, должен временно сломать инвариант. «Безопасность потока» в этом случае означает, что никакой другой поток не сможет увидеть временно прерванное состояние.
Создание программы из «поточно-ориентированных» объектов не делает всю программу «поточно-ориентированной», поскольку программа более высокого уровня может зависеть от важных инвариантных отношений между объектами. И, хотя объекты являются индивидуально потокобезопасными, у них нет возможности узнать о связях более высокого уровня, которые имеют значение для программы в целом.