Hoe zou u de uitvoering van Erlang-achtige verzenden en ontvangen in C ++?

stemmen
10

Eigenlijk, lijkt deze vraag aan twee delen bestaan:

  • Hoe te patroonherkenning te implementeren?
  • Hoe te implementeren verzenden en ontvangen (dat wil zeggen de acteur model)?

Voor het patroon dat overeenkomt deel, heb ik op zoek naar diverse projecten, zoals App en Prop . Deze zien er erg mooi, maar kon niet krijgen ze aan het werk op een recente versie (4.x) van G ++. De Felix taal lijkt ook patroonherkenning vrij goed te ondersteunen, maar is niet echt C ++.

Wat betreft de acteur model zijn er bestaande implementaties zoals ACT ++ en Theron , maar ik kon niet anders dan papieren op de voormalige te vinden , en de laatste is single-threaded alleen [zie antwoorden].

Persoonlijk heb ik acteurs met behulp van threading en een thread-safe berichtenwachtrij geïmplementeerd. Berichten hash-achtige structuren en gebruikten deze tezamen met een aantal preprocessor macro's uitgevoerd eenvoudige patroonherkenning.

Op dit moment kan ik de volgende code gebruiken om een ​​bericht te sturen:

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

En de volgende eenvoudige patroonherkenning doen ( qDebugen qPrintablezijn Qt-specifieke):

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

Echter, dit ziet er een beetje hackish voor mij, en is niet erg robuust.

Hoe zou je het doen? Miste ik een bestaand werk?

De vraag is gesteld op 02/09/2008 om 18:52
user
In andere talen...                            


7 antwoorden

stemmen
4

Een van de belangrijke dingen over Erlang is hoe de functies worden gebruikt om robuuste systemen te maken.

De zend / ontvang model is niet-sharing, en expliciet te kopiëren. De processen zelf zijn lichtgewicht threads.

Als je dat deed de wens van de robuuste eigenschappen van de Erlang model, past het beste zijn om echte processen en IPC in plaats van draden te gebruiken.

Als u wilt robuuste doorgeven van berichten al heb je misschien uiteindelijk willen serialize en deserialise de inhoud. Vooral bij typeveiligheid.

Patroonovereenkomsten in C ++ is niet altijd mooi, maar er zal een goede patroon voor dit zijn - je zal uiteindelijk het creëren van een dispatcher object dat een bepaalde vorm van polymorfisme gebruikt om te krijgen wat je wilt.

Hoewel, als je niet voorzichtig bent u uiteindelijk met xml over pijpen :)

Echt, als je de Erlang model wil je echt wilt Erlang gebruiken. Als er langzaam stukjes, ik weet zeker dat je je programma met behulp van een buitenlandse functie internet vergroten.

Het probleem over re-implementatie van onderdelen, is dat u niet een goed samenhangend bibliotheek en een oplossing te krijgen. De oplossingen die u al niet erg lijken C ++ meer.

antwoordde op 02/09/2008 om 19:49
bron van user

stemmen
11

Wat betreft de acteur model zijn er bestaande implementaties zoals ACT ++ en Theron, maar ik kon niet anders dan papieren op de voormalige te vinden, en de laatste is single-threaded alleen.

Als auteur van Theron, was ik benieuwd waarom je geloven dat het single-threaded?

Persoonlijk heb ik geïmplementeerd acteurs met behulp van threading en een thread-safe berichtenwachtrij

Dat is hoe Theron wordt uitgevoerd .. :-)

As

antwoordde op 08/10/2008 om 21:17
bron van user

stemmen
4

Ik ben momenteel de uitvoering van een acteur bibliotheek voor C ++ genaamd "acedia" (er is nog niets over het op google) dat "type matching" gebruikt. De bibliotheek is een project voor mijn scriptie en je kunt elke vorm van gegevens naar een acteur met het.

Een klein fragment:

recipient.send(23, 12.23f);

En op de ontvangende kant kan je ofwel het analyseren van de ontvangen bericht als volgt uit:

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

... of u kunt een regelset die een functie of methode aanroept voor u definiëren:

void doSomething(int, float);

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

Het is ook mogelijk om zowel het type en de waarde aan te passen:

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

De constante "WILDCARD" betekent dat enige waarde wordt acceptet. Pass zonder argumenten gelijk set alle argumenten "WILDCARD"; wat betekent dat je alleen wilt de types aan te passen.

Dit is zeker een klein fragment. Ook kunt u "case klassen" gebruiken, zoals in Scala. Ze zijn vergelijkbaar met "Kernfysica" in Erlang. Hier is een meer gedetailleerd voorbeeld:

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

Om te reageren op de gedefinieerde geval lessen kun je een acteur als volgt schrijven:

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);
    }

};

Om een ​​nieuwe acteur te maken en beginnen met het, alles wat je hoeft te schrijven is:

Acedia::spawn<SomeActor>();

Hoewel de bibliotheek niet eens beta stadium bereikte de getoonde fragmenten te werken en ik heb een eerste applicatie die op het lopen. Een belangrijk doel van de bibliotheek is om gedistribueerde programmering (ook via een netwerk) te ondersteunen.

Uw vraag is een tijdje geleden, maar als je geïnteresseerd bent in bent: laat het me weten! :)

antwoordde op 26/05/2009 om 19:14
bron van user

stemmen
0

Ik zou zeker geïnteresseerd in het kijken naar uw "acedia" bibliotheek en zou graag helpen op een manier die ik kon. Erlang heeft een aantal prachtige constructies en C ++ zeker kunnen profiteren van een dergelijke bibliotheek.

antwoordde op 30/05/2009 om 03:52
bron van user

stemmen
0

Vandaag heb ik hostet de bibliotheek op sourceforge: https://sourceforge.net/projects/acedia/

Zoals ik al eerder zei dat het een vervroegde vrijlating. Maar voel je vrij om het te bekritiseren!

antwoordde op 08/06/2009 om 19:06
bron van user

stemmen
2

U kunt het gedrag na te bootsen met behulp van Qt signaal / slot mechanisme, vooral omdat Qt signaal / slot ondersteunt multithread.

antwoordde op 09/11/2010 om 23:29
bron van user

stemmen
0

Vandaag de dag, als je wilt Erlang stijl robuust actoren in C ++, en patroonherkenning, misschien Rust is het antwoord.

Natuurlijk was dit niet in de buurt publiekelijk wanneer de OP gevraagd ~ 5 jaar geleden, en vanaf april 2014 is het nog steeds niet nog v1.0 - maar het is zeer goed verlopen en is zeker stabiliseren, genoeg van de taal kern is stabiel I denken.

En ok haar niet C ++, maar het heeft dezelfde benadering van memory management als C ++, met dien verstande dat het ondersteunt lichtgewicht taken zonder gedeeld geheugen standaard (levert vervolgens gecontroleerd bibliotheek functies voor het delen - "Arc"); Het kan direct bellen (en direct bloot) 'extern C' functies. Je kunt niet delen templated bibliotheek headers met C ++ - maar je kunt generieke dat C mimick ++ verzameling klassen (en vice versa) om de verwijzingen naar de data-structuren aan de overkant voorbij te schrijven.

antwoordde op 17/04/2014 om 07:01
bron van user

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more