Как Актеры работают по сравнению с потоками?

Есть ли хорошее и краткое объяснение того, как Актеры работают по сравнению с потоками?

Не может ли поток рассматриваться как актер и отправлять сообщения другим потокам? Я вижу некоторую разницу, но это не так понятно для меня. Могу ли я использовать Актеры на любом языке, используя потоки по-другому?

Ответ 1

Модель актера работает с передачей сообщений. Отдельным процессам (актерам) разрешено отправлять сообщения асинхронно друг другу. То, что отличает это от того, что мы обычно считаем моделью потоков, состоит в том, что существует (по крайней мере теоретически) отсутствие общего состояния. И если кто-то верит (справедливо, я думаю), что разделяемое государство является корнем всего зла, то модель актера становится очень привлекательной.

Однако мы не должны волноваться. Модель актера не (в отличие от некоторых утверждений) делает невозможным наличие взаимоблокировок. Модель актера также не мешает вам конкурировать за ресурсы между различными процессами - очереди сообщений, например. Модель только "заблокирована" выше определенного уровня. На более низком уровне для координации очередей сообщений требуется блокировка.

Не может ли поток восприниматься как актер и отправлять сообщения другим потокам?

Хорошо, да и нет. Нет, если вы просто используете подход по помещению мьютексов в области разделяемой памяти. Затем потоки разделяют это состояние - они оба имеют доступ к этой памяти, могут читать, перезаписывать и т.д. Но вы можете создать модель актера поверх модели потоковой передачи, и действительно, вся актерская реализация имеет потоки под. Я взломал что-то вроде этого (очень плохо), предоставив каждому потоку очередь, охраняемую мьютексом - просто для удовольствия. Чтобы получить представление о том, как управляется импеданс актера, см. мой вопрос с года назад.

Могу ли я использовать модель актера на любом языке, используя потоки по-разному?

Да, но это займет немного больше работы. У вашего любимого языка вполне может быть библиотека для передачи сообщений, так что это будет первое, что нужно исследовать. Кроме того, вам следует исследовать использование неизменяемых структур данных. Обратите внимание, что если структура данных является неизменной, то вы по существу решаете проблему с разделяемым состоянием - несколько потоков могут содержать ссылки на неизменяемые данные без каких-либо неприятных последствий. Существует причина, по которой актерские языки также являются функциональными языками (erlang, scala).

Вы также можете взглянуть на Software Transactional Memory, которая является другой, но также привлекательной моделью. Clojure - мой любимый пример.

Ответ 2

Я бы не сказал, что актеры всегда передают сообщения асинхронно - это будет слишком медленно. В этом случае проект JActor использует двухсторонние сообщения (запрос/ответ) для лучшей модели вызова метода. И большинство запросов обслуживаются синхронно.

JActor (библиотека Java) также не использует блокировки. Только некоторые атомные и параллельные структуры данных с несколькими семафорами, которые были добавлены. Передача сообщений составляет около 0,8 миллиарда сообщений в секунду.

https://github.com/laforge49/JActor