Методы, связанные с классом хорошо справляются со своей задачей, но когда мы используем ООП в многопоточной среде, то помимо классов и объектов появляются еще и потоки. В языке С++ нет такого понятия, как поток, а следовательно компилятор не делает каких-либо проверок относительно них. И ситуация начинает повторяться. Хоть изменение состояния и локализовано в методах, но сказать когда и в каком потоке будет выполняться этот метод в общем случае невозможно. Потоки как бы проникают сквозь барьер инкапсуляции, и это может разрушить состояние объекта. В теории компьютерных наук такая ситуация называется гонками – ситуация, в которой два (и более) процесса считывают или записывают данные одновременно, а конечный результат зависит от того, какой из них был первым.
Чтобы избежать такой ситуации в Java, например, есть такой атрибут для методов как synchronized, а в языках С++ и Delphi таких атрибутов нет, и поэтому, необходимо код каждого публичного метода защищать критической секцией.
Мой опыт создания ядра библиотеки act-o говорит о том, что это очень плохая идея – писать программы в стиле ООП доступном на С++, защищая публичные методы критическими секциями. Потому, что почти сразу я столкнулся с явлением взаимоблокировки и разобраться, что и почему блокируется, было просто невозможно. Я отказался от ООП в пользу процедурного стиля.
Один из возможных способов избежать вышеописанных проблем – это вернуться к первоначальной концепции ООП, предложенной Аланом Кеем.
Алан Кей – это человек, который создал язык программирования Smalltalk, и ввел термин «объектно-ориентированный». Тогда он вкладывал в этот термин три основных идее:
- Объект – базовая единица объектно-ориентированной системы.
- Объекты могут обладать состоянием.
- Посылка сообщений – единственный способ обмена информацией между объектами.
Благодаря очереди сообщений становится не важно, какой поток послал сообщение, важно только в каком потоке оно будет обработано. В результате инкапсуляция не нарушается. А, вводя в систему правило, что объект может обрабатывать только одно сообщение в одном потоке одновременно, отпадает необходимость в наличии критических секций в методах обработки сообщений. В результате не возникает ситуация гонок.
Все это краткое описание тех идей, на основе которых построена библиотека act-o, и именно такой механизм организации взаимодействия между объектами она предоставляет.
В недалеком будущем я опубликую небольшое исследование об истории ООП и о том, как оно от определения, данного Аланом Кеем, превратилось в то, чем оно является сейчас. Похоже, что модель актеров – это начальная идея ООП, но в новой обертке.
Также расскажу о таком понятии как Inversion of Control (IoC) и почему оно тоже может представлять проблему не только в многопоточном ООП, но и в классическом.
Оставайтесь на связи… :-)
Комментариев нет:
Отправить комментарий