Windows для профессионалов


Создание инверсных семафоров и типов данных, безопасных в многопоточной среде - часть 4


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

В классе CInterlockedType также присутствуют три невиртуальные защищенные функции, которые будут вызываться производным классом. Две функции GetVal возвращают текущее значение объекта данных. В отладочных версиях файла обе эти функции сначала проверяют, охраняется ли объект данных. Если бы он не охранял ся, GetVal могла бы вернуть значение объекта, а затем позволить другому потоку изменить его до того, как первый поток успеет что-то сделать с этим значением. Я предполагаю, что вызывающий поток получает значение объекта для того, чтобы как-то изменить его. Поэтому функции GetVal требуют от вызывающего потока охраны доступа к данным. Определив, что данные охраняются, функции GetVal возвращают текущее значение.

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

Третья невиртуальная защищенная функция-член — SetVal. Желая модифицировать данные, любая функция-члсн производного класса должна защитить доступ к этим данным, а потом вызвать функцию SetVal. Как и GetVal, функция SetVal сначала проводит отладочную проверку, чтобы убедиться, не забыл ли код производного класса защитить доступ к данным. Затем SetVal проверяет, действительно ли данные изменяются. Если да, SetVal сохраняет старое значение, присваивает объекту новое значение и вызывает виртуальную защищенную функцию-члеи OnValChanged, передавая ей оба значения. В классе CInterlockedType последняя функция реализована так, что она ничего не делает. Вы можете использовать эту функцию-член для того, чтобы расширить возможности своего производного класса, но об этом мы поговорим, когда дойдем до рассмотрения класса CWhenZero.




Начало  Назад  Вперед



Книжный магазин