C++에서 Erlang과 유사한 보내기 및 받기를 어떻게 구현합니까?

StackOverflow https://stackoverflow.com/questions/40423

  •  09-06-2019
  •  | 
  •  

문제

실제로 이 질문은 두 부분으로 구성된 것 같습니다.

  • 패턴 일치를 구현하는 방법은 무엇입니까?
  • 구현 방법 보내고 받기 (즉.배우 모델)?

패턴 매칭 부분에 관해서는 다음과 같은 다양한 프로젝트를 살펴 보았습니다. 그리고 소품.꽤 괜찮아 보이지만 최신 버전(4.x)의 g++에서는 작동하지 않습니다.그만큼 펠릭스 언어도 패턴 일치를 꽤 잘 지원하는 것 같지만 실제로는 C++가 아닙니다.

에 관해서는 배우 모델, ACT++와 같은 기존 구현이 있으며 테론, 하지만 전자에 관한 서류 외에는 아무것도 찾을 수 없었습니다., 후자는 단일 스레드 전용입니다. [답변 보기].

개인적으로 저는 스레딩과 스레드로부터 안전한 메시지 대기열을 사용하여 액터를 구현했습니다.메시지는 해시와 유사한 구조이며 이를 여러 전처리기 매크로와 함께 사용하여 간단한 패턴 일치를 구현했습니다.

지금은 다음 코드를 사용하여 메시지를 보낼 수 있습니다.

(new Message(this))
    ->set("foo", "bar")
    ->set("baz", 123)
    ->send(recipient);

그리고 간단한 패턴 일치를 수행하려면 다음을 수행합니다(qDebug 그리고 qPrintable Qt에 따라 다름):

receive_and_match(m)
    match_key("foo")    { qDebug("foo: %s", qPrintable(m->value("foo").toString())); }
    or_match_key("baz") { qDebug("baz: %d", m->value("baz").toInt()); }
    or_match_ignore
end_receive

그러나 이것은 나에게 약간 해킹처럼 보이고 그다지 강력하지 않습니다.

어떻게 하시겠습니까?기존 작업을 놓쳤나요?

도움이 되었습니까?

해결책

erlang의 중요한 점 중 하나는 강력한 시스템을 만들기 위해 기능을 사용하는 방법입니다.

보내기/받기 모델은 공유하지 않고 명시적으로 복사합니다.프로세스 자체는 경량 스레드입니다.

Erlang 모델의 강력한 속성을 원한다면 스레드보다는 실제 프로세스와 IPC를 사용하는 것이 가장 좋습니다.

강력한 메시지 전달을 원한다면 결국 내용을 직렬화 및 역직렬화하고 싶을 수도 있습니다.특히 유형 안전성이 중요합니다.

C++의 패턴 일치가 항상 좋은 것은 아니지만 이를 위한 좋은 패턴이 있을 것입니다. 결국 원하는 것을 얻기 위해 일종의 다형성을 사용하는 디스패처 개체를 생성하게 됩니다.

조심하지 않으면 파이프를 통한 XML로 끝나게 됩니다 :)

실제로, 얼랭 모델을 원한다면 정말 얼랭을 사용하고 싶을 것입니다.느린 비트가 있는 경우 외부 기능 인터넷을 사용하여 프로그램을 확장할 수 있다고 확신합니다.

부품을 다시 구현할 때의 문제는 응집력 있는 좋은 라이브러리와 솔루션을 얻을 수 없다는 것입니다.이미 사용하고 있는 솔루션은 더 이상 C++처럼 보이지 않습니다.

다른 팁

배우 모델의 경우 ACT ++ 및 Theron과 같은 기존 구현이 있지만 전자의 논문 외에는 아무것도 찾을 수 없었고 후자는 단일 스레드 만 있습니다.

Theron의 저자로서 저는 왜 이것이 단일 스레드라고 믿는지 궁금합니다.

개인적으로, 나는 스레딩과 스레드 안전 메시지 큐를 사용하여 배우를 구현했습니다.

Theron이 구현되는 방식입니다.:-)

금연 건강 증진 협회

저는 현재 "유형 일치"를 사용하는 "acedia"(Google에는 아직 이에 대한 내용이 없음)라는 C++용 액터 라이브러리를 구현하고 있습니다.라이브러리는 내 석사 논문을 위한 프로젝트이며 이를 통해 배우에게 모든 종류의 데이터를 보낼 수 있습니다.

작은 조각:

recipient.send(23, 12.23f);

수신자 측에서는 다음과 같이 수신된 메시지를 분석할 수 있습니다.

Message msg = receive();
if (msg.match<int, float>() { ... }

...또는 함수나 메소드를 호출하는 규칙 세트를 정의할 수 있습니다.

void doSomething(int, float);

InvokeRuleSet irs;
irs.add(on<int, float>() >> doSomething);
receiveAndInvoke(irs);

유형과 값을 모두 일치시키는 것도 가능합니다.

Message msg = receive();
if (msg.match<int, float>(42, WILDCARD) { ... }
else if (msg.match<int, float>() { ... }

상수 "WILDCARD"는 모든 값이 허용된다는 의미입니다.인수를 전달하지 않으면 모든 인수를 "WILDCARD"로 설정합니다.즉, 유형만 일치시키려는 것입니다.

이것은 확실히 작은 조각입니다.또한 Scala에서와 같이 "케이스 클래스"를 사용할 수도 있습니다.이는 erlang의 "atomics"와 유사합니다.더 자세한 예는 다음과 같습니다.

ACEDIA_DECLARE_CASE_CLASS(ShutdownMessage)
ACEDIA_DECLARE_CASE_CLASS(Event1)
ACEDIA_DECLARE_CASE_CLASS(Event2)

정의된 케이스 클래스에 반응하려면 다음과 같이 액터를 작성할 수 있습니다.

class SomeActor : public Actor
{

  void shutdown() { done = true; }
  void handleEvent1();
  void handleEvent1();

  public:

    SomeActor() : done(false) { }

    virtual void act()
    {
      InvokeRuleSet irs;
      irs
        .add(on<ShutdownMessage>() >> method(&SomeActor::shutdown))
        .add(on<Event1>() >> method(&SomeActor::handleEvent1))
        .add(on<Event2>() >> method(&SomeActor::handleEvent2))
      ;
      while (!done) receiveAndInvoke(irs);
    }

};

새 액터를 생성하고 시작하려면 다음과 같이 작성하면 됩니다:

Acedia::spawn<SomeActor>();

라이브러리가 베타 경기장에 도달하지 않았더라도 표시된 스니펫은 작동하며 첫 번째 애플리케이션이 실행 중입니다.라이브러리의 주요 목표 중 하나는 분산 프로그래밍(또한 네트워크를 통한)을 지원하는 것입니다.

귀하의 질문은 오래 전이지만 관심이 있으시면 다음을 수행하십시오.알려줘요!:)

특히 Qt의 신호/슬롯이 다중 스레드를 지원하므로 Qt의 신호/슬롯 메커니즘을 사용하여 동작을 모방할 수 있습니다.

나는 확실히 당신의 "acedia" 라이브러리를 보는 데 관심이 있고 내가 할 수 있는 어떤 방식으로든 도움을 주고 싶습니다.Erlang에는 몇 가지 훌륭한 구성이 있으며 C++는 이러한 라이브러리로부터 확실히 이점을 얻을 수 있습니다.

오늘 저는 sourceforge에서 라이브러리를 호스팅했습니다. https://sourceforge.net/projects/acedia/

앞서 말했듯이 조기 출시입니다.하지만 자유롭게 비판해 보세요!

오늘날 C ++의 Erlang 스타일의 강력한 배우와 패턴 매칭을 원한다면 Rust가 답일 수 있습니다.

물론 이것은 OP가 약 5년 전에 요청했을 때 공개적으로 존재하지 않았으며 2014년 4월 현재 아직 v1.0이 아닙니다. 그러나 매우 잘 진행되고 있으며 확실히 안정화되고 있으며 언어 핵심이 충분히 안정적입니다. 생각하다.

C++는 아니지만 메모리 관리에 대한 접근 방식은 C++와 동일합니다. 단, 기본적으로 공유 메모리가 없는 경량 작업을 지원합니다(그런 다음 공유를 위한 제어된 라이브러리 기능 제공 - "Arc").'extern C' 함수를 직접 호출(및 직접 노출)할 수 있습니다.템플릿 기반 라이브러리 헤더를 C++와 공유할 수는 없지만 C++ 컬렉션 클래스를 모방하는 제네릭을 작성하여(또는 그 반대로) 데이터 구조에 대한 참조를 전달할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top