Правильно ли мое описание актерской модели?


13

Если я понял, модель актера похожа на объектную модель, но с некоторыми отличиями:

  1. КАЖДЫЙ объект порождает свой отдельный поток, и это не проблема, даже если у вас есть тысячи объектов.
  2. Актеры взаимодействуют не с помощью вызова функций и получения возвращаемых значений, а с помощью отправки и получения сообщений.
  3. Если вы не нарушите эту модель, ваше приложение будет использовать параллелизм на полную мощность без каких-либо рисков гоночных условий.
  4. Все, что вы можете сделать в ОО, вы можете сделать, используя актеров, но лучше, проблема в том, что все, что мы кодировали в последние годы, было основано на ОО - но переход неизбежен.

Например, предположим, что мне нужно определить класс / вектор трехмерного вектора, создать два экземпляра и вызвать для них операцию суммирования.

ОБЪЕКТНО-ОРИЕНТИРОВАННЫЙ:

class V3d {
   constructor V3d(x,y,z) //bla
   float x,y,z;
   function sum(V3d b) 
   { 
      return V3d(x+b.x,y+b.y,z+b.z); 
   }
}

//using:
mySum = V3d(1,2,3).sum(V3d(3,2,1)) //creates 2 instances, sum, returns instantly
drawPoint(mySum) //uses the result

МОДЕЛЬ АКТЕРА:

actor V3d 
{
    constructor V3d(x,y,z) //bla
    float x,y,z;
    loop 
    {
       receive 'sum',b:V3d :
           send(caller,'sumResult',V3d(x+b.x,y+b.y,z+b.z))
    }
 }

//using:
send(V3d(1,2,3),'sum',V3d(3,2,1)) //creates 2 instances, send to the first one a request to sum with the second one

loop 
{
   receive 'sumResult',result:
      drawPoint(result) //receives result and draws it
}

Это оно? Или я совершенно не прав?


Легкие субъекты, микроагенты или компоненты потока данных не обязательно используют свои собственные потоки. :-) Проверьте следующие термины: актерское программирование, агентное программирование, программирование на основе потоков данных. Они очень похожи, но имеют разные ограничения. О, я задам это как вопрос ;-)
inf3rno

Ответы:


12

Краткий ответ - нет, это не правильно.

  1. начинается достаточно корректно (каждый актер, по крайней мере, потенциально выполняется как независимый поток), но затем в значительной степени сбивается с пути. В модели нет ничего, что заставляло бы работать много потоков - это зависит от реализации. Самое большее, простота создания большого количества потоков оказывает давление на реализацию, чтобы обеспечить эффективную многопоточность. По крайней мере, что касается модели, любое сходство между актерами и объектами в основном случайно. «Объект» имеет довольно специфические последствия того, как вы комбинируете код и данные. Актер обычно включает в себя как код, так и данные, но мало что говорит о том, как они объединяются (кроме того факта, что единственными данными, видимыми для внешнего мира, являются сообщения).

  2. Обычный способ описания взаимодействия - отправка сообщений, да. У меня нет удобной цитаты, но кто-то давно доказал, что такие механизмы, как виртуальные функции C ++, изоморфны отправке сообщений (так как виртуальные функции обычно реализуются, вы используете смещение в vtable - но если вы вместо этого отправил смещение в таблицу сообщений, эффект будет таким же).

  3. Это не так просто. Если вы сможете найти копию, Генри Бейкер (вместе с кем-то, чье имя я сейчас не помню) написал статью о правилах, необходимых для согласованности данных в модели актера.

  4. «Лучше» в лучшем случае очень субъективно. Некоторые проблемы очень параллельны по своей природе и действительно включают в себя большое количество автономных сущностей с минимальным взаимодействием, которое в основном асинхронно. В таком случае модель актера действительно может работать очень хорошо. Для других проблем это действительно не так. Некоторые проблемы почти полностью носят серийный характер. Другие могут выполняться параллельно, но при этом все же требуется тесная синхронизация между этими действиями (например, по существу режим, подобный SIMD, когда вы выполняете одну инструкцию за раз, но каждая инструкция воздействует на большое количество элементов данных). Конечно, можно решить оба этих типа проблем, используя модель актера, но для таких задач часто требуется изрядное количество дополнительной работы за небольшую или нулевую прибыль взамен.


Там нет никакой связи между количеством актеров и количеством потоков; модель актора гарантирует, что данный экземпляр будет обрабатываться только одним потоком за раз, поэтому ваши акторы уже поточно-ориентированы, и вам не нужно использовать стратегии синхронизации и блокировки внутри них.
Роб Кроуфорд

@RobCrawford: это один (довольно тривиальный) способ обеспечения согласованности данных в модели Actor. Статья Хьюитта / Бейкера охватывает больше возможностей, таких как множественные копии актера, работающего в отдельных потоках (хм ... глядя на мой ответ, мне интересно, не могу ли я честно вспомнить имя Карла Хьюитта в то время, или будучи ироничным, когда я это написал).
Джерри Гроб

Разве асинхронность передачи сообщений не является существенным элементом модели? Это, безусловно, помешало бы его изоморфности при вызовах виртуальных функций, которые по своей природе являются синхронными. Или это различие не имеет значения с какой-то точки зрения?
мальчик

2

Относительно 1: я работал с однопоточным приложением, смоделированным актером, так что вполне возможно игнорировать большое количество потоков, которое это предлагает. AFAIK, потоки не являются легкими объектами в любом случае, поэтому, вероятно, не желательно иметь один для каждого актера, в зависимости от того, сколько актеров вы используете.

Относительно 3: Я почти уверен, что условия гонки могут произойти в системах, смоделированных актерами, просто из-за логики программирования?

Относительно 4: определить «лучше»? Мой опыт показывает, что асинхронную логику гораздо сложнее читать, чем синхронную логику. Например, в приведенном выше примере вы не знаете, какая операция отвечает за какой результат, поэтому необходимо выполнить дополнительное отслеживание сообщений. Как только это добавляется, а другие сообщения входят и выходят в логику, цель кода распределяется по нескольким функциям отправки / получения.

Сказав все это, я большой поклонник использования актерской модели для верхних уровней приложения. Это может облегчить разделение, поскольку добавить зависимости немного сложнее, чем добавить функцию. У меня также нет большого опыта работы с языками более высокого уровня, чем языки Java, и другие парадигмы могут поддерживать асинхронность более фундаментальным образом.


Относительно №1: Ну, «нить» может относиться ко многим вещам. Правда, потоки ОС обычно довольно тяжелые, но существуют языковые среды выполнения, которые внутренне обрабатывают сотни, тысячи и даже миллионы «потоков» выполнения в небольшом количестве потоков ОС. В некоторых реализациях такие модели, очевидно, масштабируются до десятков ядер (я видел заявления о том, что последние версии GHC хорошо работают с 32 ядрами).
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.