FSST - Hardwarenahe Programmierung

Active Objects

Based on Herb Sutters Klasse "Active Object"

Definition von Aktive Objekte in UML sind aktive Klassen und somit aktive Objekte in einem eigenen Thread von Operationen vorhanden und haben einen eigenen Adressraum. Die Ausführung von Code in Bezug auf den Kontrolfluss betrachtet wird, können aktive Objekte diesen Aktivitätsfluss starten oder steuern, was in passiven Objekten grundsätzlich nicht möglich ist, da sie eigentlich nur Daten speichern bzw. teilen. Aktive Objekte sind also sequentiell und tun etwas: Ändern von Variablen, Ändern des Programmverhaltens usw. In UML unterscheiden sich aktive Klassen und Objekte dadurch, dass sie einen dickeren Rahmen haben als passive Objekte. (siehe auch Active Object Pattern)

Herb Sutters Klasse "Active Object" könnte so aussehen, als wäre sie mit mbed-events implementiert:

Active Object using mbed-events

class Active
{
private:
    EventQueue _queue;
    Thread _thread;

public:
    // Constructor spawns object-specific thread in background
    Active()
    {
        _thread.start(callback(&_queue, &EventQueue::dispatch_forever));
    }

    // Destructor waits for pending events to finish and gracefully cleans up thread
    ~Active()
    {
        _queue.break_dispatch();
        _thread.join();
    }

    // Send passes messages to thread running in the background
    void Send(Callback<void()> m)
    {
        _queue.call(m);
    }
};

Es gibt jedoch einige Bedenken hinsichtlich der Basisimplementierung von Active Objects, insbesondere den Ressourcen, die von jedem Objekt zur Verwaltung seines eigenen Threads verwendet werden. Mit den in mbed-events verfügbaren Tools können auch zusammensetzbare Active Objects erstellen werden, die die Ausführungsressourcen einer übergeordneten Event Queue (Ereigniswarteschlange) gemeinsam nutzen können:

Active Object using mbed-events with shared resources

class ActiveShare
{
private:
    EventQueue _queue;
    Thread *_thread;

public:
    // Constructor chains event queue to parent if provided, otherwise is lazily allocates a thread
    ActiveShare(ActiveShare *parent = NULL)
        : _thread(NULL)
    {
        if (parent) {
            _queue.chain(&parent->_queue);
        } else {
            _thread = new Thread;
            _thread->start(callback(&_queue, &EventQueue::dispatch_forever));
        }
    }

    // Destructor will unchain the event queue from its parent if necessary
    ~ActiveShare()
    {
        if (_thread) {
            _queue.break_dispatch();
            _thread->join();
            delete _thread;
        }
    }

    // Send passes messages to thread running in the background
    void Send(Callback<void()> m)
    {
        _queue.call(m);
    }
};

All wikipages