내가 이해한다면, 액터 모델은 오브젝트 모델과 비슷하지만 약간의 차이점이 있습니다.
- 모든 객체는 별도의 스레드로 생성되며 수천 개의 객체가 있어도 문제가되지 않습니다.
- 액터는 함수를 호출하고 반환 값을 가져 오는 대신 상호 작용하지 않고 메시지를 보내고받습니다.
- 해당 모델을 위반하지 않으면 앱은 경쟁 조건의 위험없이 전체 기능에 동시성을 사용합니다.
- OO에서 할 수있는 모든 것은 액터를 사용하여 할 수 있지만 더 나은 문제는 지난 몇 년 동안 코딩 한 모든 것이 OO를 기반으로한다는 것입니다. 그러나 전환이 임박했습니다.
예를 들어, 3d 벡터 클래스 / 액터를 정의하고 두 개의 인스턴스를 생성하고 그에 대한 합 연산을 호출해야한다고 가정하십시오.
객체 지향 :
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
}
그게 다야? 아니면 내가 완전히 틀렸어?
답변
짧은 대답은 아니요, 맞지 않습니다.
-
합리적으로 올바른 시작 (각 액터는 적어도 독립적 인 스레드로 실행될 수 있음), 그러나 대부분 레일에서 벗어납니다. 많은 스레드가 제대로 작동 하는 모델 에 대해서는 아무것도 없습니다 . 구현에 달려 있습니다. 기껏해야 많은 스레드를 쉽게 만들 수 있으므로 효율적인 스레딩을 제공해야합니다. 적어도 모델이 신경 쓰는 한, 액터와 오브젝트 사이의 유사점은 대부분 우연입니다. “객체”는 코드와 데이터를 결합하는 방법에 대해 상당히 구체적인 영향을 미칩니다. 액터는 일반적으로 코드와 데이터를 모두 포함하지만 외부 세계에서 볼 수있는 유일한 데이터는 메시지라는 사실을 제외하고는 어떻게 결합되는지에 대해 거의 암시하지 않습니다.
-
상호 작용을 설명하는 일반적인 방법은 메시지 전송입니다. 인용이 편리하지는 않지만 누군가가 C ++ 가상 함수와 같은 메커니즘이 메시지 전송에 동형 적이라는 것을 이미 입증했습니다. 대신 메시지 테이블에 오프셋을 보냈을 때 효과는 동일합니다.
-
그렇게 간단하지 않습니다. 사본을 찾을 수 있다면 Henry Baker (지금 기억하지 못하는 다른 사람과 함께)는 Actor 모델의 데이터 일관성에 필요한 규칙에 관한 논문을 썼습니다.
-
“더 나은”것은 가장 주관적입니다. 일부 문제는 본질적으로 매우 병렬 적이며, 주로 비동기적인 상호 작용을 최소화하면서 본질적으로 많은 자율적 인 엔터티를 포함합니다. 이 경우 액터 모델이 실제로 잘 작동 할 수 있습니다. 다른 문제의 경우에는 실제로 그렇지 않습니다. 일부 문제는 본질적으로 거의 전적으로 직렬입니다. 다른 것들은 병렬로 실행될 수 있지만 여전히 그 동작들 사이의 긴밀한 동기화가 필요합니다 (예를 들어, 한 번에 하나의 명령을 실행하지만 각 명령은 많은 수의 데이터 항목에 작용하는 SIMD와 유사한 모드). 액터 모델을 사용하여 이러한 두 가지 유형의 문제를 모두 해결할 수는 있지만, 이러한 문제의 경우 대가가 거의 또는 전혀없이 상당한 양의 추가 작업이 필요합니다.
답변
1에 관해서 : 나는 단일 스레드 액터 모델링 응용 프로그램으로 작업 했으므로 이것이 제안하는 큰 스레드 번호를 무시하는 것이 가능합니다. AFAIK, 스레드는 어떤 방법으로도 가벼운 객체가 아니므로 사용하는 액터 수에 따라 각 액터마다 하나씩 사용하는 것은 바람직하지 않습니다.
3 관련하여 : 단순히 프로그래밍 논리로 인해 액터 모델링 시스템에서 경쟁 조건이 발생할 수 있다고 확신합니까?
4 : 더 나은 정의? 내 경험에 따르면 비동기 논리는 동기식 항목보다 읽기가 훨씬 어려울 수 있습니다. 예를 들어, 위의 예에서 어떤 작업이 어떤 결과를 담당하는지 모르므로 추가 메시지 추적이 필요합니다. 일단 그것이 추가되고 다른 메시지가 들어오고 나가면 로직에 포함되며 코드의 의도는 여러 보내기 / 받기 기능에 분산됩니다.
그 모든 것을 말했지만, 나는 응용 프로그램의 상위 계층에 대한 액터 모델 사용의 큰 팬입니다. 의존성을 추가하는 것이 함수를 추가하는 것보다 조금 어렵 기 때문에 디커플링을 더 쉽게 할 수 있습니다. 또한 Java 언어보다 더 높은 수준의 경험이 없으며 다른 패러다임이 더 근본적인 방식으로 비동기 성을 지원할 수 있습니다.