Si entendí, el modelo de actor es igual que el modelo de objetos, pero con algunas diferencias:
- CADA objeto genera su propio hilo separado y no es un problema incluso cuando tiene miles de objetos.
- Los actores no interactúan llamando funciones y obteniendo valores de retorno, sino enviando y recibiendo mensajes.
- Si no viola ese modelo, su aplicación utilizará la concurrencia en toda su potencia sin ningún riesgo de condiciones de carrera.
- Todo lo que puede hacer en OO lo puede hacer con actores, pero mejor, el problema es que todo lo que codificamos en los últimos años se basó en OO, pero una transición es inminente.
Entonces, por ejemplo, supongamos que tengo que definir una clase / actor de vector 3d, crear dos instancias y llamar a una operación de suma en ellas.
ORIENTADO A OBJETOS:
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
MODELO DE ACTOR:
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
}
¿Es asi? ¿O estoy completamente equivocado?
Respuestas:
La respuesta corta es no, no es correcta.
comienza razonablemente correcto (cada actor al menos potencialmente se ejecuta como un hilo independiente), pero luego se sale de los rieles. No hay nada en el modelo que haga que muchos hilos funcionen bien, eso depende de la implementación. A lo sumo, la facilidad de crear muchos subprocesos ejerce presión sobre la implementación para proporcionar subprocesos eficientes. Al menos en lo que a la modelo le importa, cualquier parecido entre actores y objetos es mayormente una coincidencia. "Objeto" tiene implicaciones bastante específicas sobre cómo combinar código y datos. Un actor generalmente involucrará tanto código como datos, pero implica poco sobre cómo se combinan (aparte del hecho de que los únicos datos visibles para el mundo exterior son los mensajes).
La forma habitual de describir la interacción es mediante el envío de mensajes, sí. No tengo una cita a mano, pero alguien demostró hace mucho tiempo que mecanismos como las funciones virtuales de C ++ son isomórficos para el envío de mensajes (como las funciones virtuales se implementan normalmente, está utilizando un desplazamiento en una tabla virtual, pero si usted envió un desplazamiento a una tabla de mensajes, el efecto sería el mismo).
No es tan simple. Si puede encontrar una copia, Henry Baker (con otra persona cuyo nombre no recuerdo en este momento) escribió un documento sobre las reglas necesarias para la coherencia de los datos en el modelo de actor.
"Mejor" es altamente subjetivo en el mejor de los casos. Algunos problemas son de naturaleza muy paralela y realmente involucran una gran cantidad de entidades esencialmente autónomas, con una interacción mínima que es principalmente asíncrona. Cuando ese es el caso, el modelo de actor puede funcionar muy bien. Para otros problemas, ese no es realmente el caso. Algunos problemas son casi por completo de naturaleza serial. Otros pueden ejecutarse en paralelo, pero aún requieren una estrecha sincronización entre esas acciones (por ejemplo, esencialmente un modo similar a SIMD, donde ejecuta una instrucción a la vez, pero cada instrucción actúa sobre una gran cantidad de elementos de datos). Ciertamente, es posible resolver estos dos tipos de problemas utilizando el modelo de actor, pero para tales problemas, a menudo implica una buena cantidad de trabajo extra por poco o ningún beneficio a cambio.
fuente
Con respecto a 1: he trabajado con una aplicación modelada de actor de un solo subproceso (ish), por lo que es muy posible ignorar el gran número de hilos que esto sugiere. AFAIK, los hilos no son objetos livianos de ninguna manera, por lo que probablemente no sea deseable tener uno para cada actor, dependiendo de cuántos actores esté usando.
Con respecto a 3: ¿estoy bastante seguro de que las condiciones de carrera pueden ocurrir en sistemas modelados por actores simplemente debido a la lógica de programación?
En cuanto a 4: ¿Definir 'mejor'? Mi experiencia ha sido que la lógica asincrónica puede ser mucho más difícil de leer que las cosas sincrónicas. por ejemplo, en su ejemplo anterior, no sabe qué operación es responsable de qué resultado, por lo que debe realizar un seguimiento adicional de mensajes. Una vez que se agrega eso y se incluyen otros mensajes de entrada y salida en la lógica, la intención del código se extiende a través de varias funciones de envío / recepción.
Dicho todo esto, soy un gran admirador del uso del modelo de actor para las capas superiores de una aplicación. Puede facilitar el desacoplamiento, ya que agregar dependencias es un poco más difícil que agregar una función. Tampoco tengo mucha experiencia con un nivel más alto que los lenguajes Java, y otros paradigmas pueden admitir la asincronía de una manera más fundamental.
fuente