<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>http://dev.kaibel.net/index.php?action=history&amp;feed=atom&amp;title=Reactor-Entwurfsmuster_%28Reactor_Pattern%29</id>
	<title>Reactor-Entwurfsmuster (Reactor Pattern) - Versionsgeschichte</title>
	<link rel="self" type="application/atom+xml" href="http://dev.kaibel.net/index.php?action=history&amp;feed=atom&amp;title=Reactor-Entwurfsmuster_%28Reactor_Pattern%29"/>
	<link rel="alternate" type="text/html" href="http://dev.kaibel.net/index.php?title=Reactor-Entwurfsmuster_(Reactor_Pattern)&amp;action=history"/>
	<updated>2026-08-25T03:39:50Z</updated>
	<subtitle>Versionsgeschichte dieser Seite in dev.kaibel.net</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>http://dev.kaibel.net/index.php?title=Reactor-Entwurfsmuster_(Reactor_Pattern)&amp;diff=77&amp;oldid=prev</id>
		<title>PhilKa: Die Seite wurde neu angelegt: „= Reactor-Entwurfsmuster (Reactor Pattern) =  Das &#039;&#039;&#039;Reactor-Entwurfsmuster&#039;&#039;&#039; ist ein Entwurfsmuster aus der Kategorie der &#039;&#039;&#039;Verhaltensmuster&#039;&#039;&#039;, das häufig in &#039;&#039;&#039;ereignisgesteuerten&#039;&#039;&#039; Systemen verwendet wird – insbesondere in &#039;&#039;&#039;Netzwerkservern&#039;&#039;&#039; und &#039;&#039;&#039;asynchronen Anwendungen&#039;&#039;&#039;.  Es dient dazu, mehrere gleichzeitige Ereignisse (z. B. eingehende Verbindungen, eingehende Daten oder Timer) effizient zu verarbeiten, ohne für jedes Ereignis einen ei…“</title>
		<link rel="alternate" type="text/html" href="http://dev.kaibel.net/index.php?title=Reactor-Entwurfsmuster_(Reactor_Pattern)&amp;diff=77&amp;oldid=prev"/>
		<updated>2025-10-30T11:35:18Z</updated>

		<summary type="html">&lt;p&gt;Die Seite wurde neu angelegt: „= Reactor-Entwurfsmuster (Reactor Pattern) =  Das &amp;#039;&amp;#039;&amp;#039;Reactor-Entwurfsmuster&amp;#039;&amp;#039;&amp;#039; ist ein Entwurfsmuster aus der Kategorie der &amp;#039;&amp;#039;&amp;#039;Verhaltensmuster&amp;#039;&amp;#039;&amp;#039;, das häufig in &amp;#039;&amp;#039;&amp;#039;ereignisgesteuerten&amp;#039;&amp;#039;&amp;#039; Systemen verwendet wird – insbesondere in &amp;#039;&amp;#039;&amp;#039;Netzwerkservern&amp;#039;&amp;#039;&amp;#039; und &amp;#039;&amp;#039;&amp;#039;asynchronen Anwendungen&amp;#039;&amp;#039;&amp;#039;.  Es dient dazu, mehrere gleichzeitige Ereignisse (z. B. eingehende Verbindungen, eingehende Daten oder Timer) effizient zu verarbeiten, ohne für jedes Ereignis einen ei…“&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Neue Seite&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= Reactor-Entwurfsmuster (Reactor Pattern) =&lt;br /&gt;
&lt;br /&gt;
Das &amp;#039;&amp;#039;&amp;#039;Reactor-Entwurfsmuster&amp;#039;&amp;#039;&amp;#039; ist ein Entwurfsmuster aus der Kategorie der &amp;#039;&amp;#039;&amp;#039;Verhaltensmuster&amp;#039;&amp;#039;&amp;#039;, das häufig in &amp;#039;&amp;#039;&amp;#039;ereignisgesteuerten&amp;#039;&amp;#039;&amp;#039; Systemen verwendet wird – insbesondere in &amp;#039;&amp;#039;&amp;#039;Netzwerkservern&amp;#039;&amp;#039;&amp;#039; und &amp;#039;&amp;#039;&amp;#039;asynchronen Anwendungen&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Es dient dazu, mehrere gleichzeitige Ereignisse (z. B. eingehende Verbindungen, eingehende Daten oder Timer) effizient zu verarbeiten, ohne für jedes Ereignis einen eigenen Thread zu starten.&lt;br /&gt;
&lt;br /&gt;
== Grundidee ==&lt;br /&gt;
&lt;br /&gt;
Der Reactor ist eine zentrale &amp;#039;&amp;#039;&amp;#039;Ereignisverteiler-Komponente&amp;#039;&amp;#039;&amp;#039; (Event Demultiplexer), die auf verschiedene Eingabekanäle (z. B. Sockets) wartet.  &lt;br /&gt;
Wenn ein Ereignis eintritt, &amp;#039;&amp;#039;&amp;#039;delegiert&amp;#039;&amp;#039;&amp;#039; der Reactor die Bearbeitung an die zuständige &amp;#039;&amp;#039;&amp;#039;Event-Handler-Komponente&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Das Muster trennt also:&lt;br /&gt;
* die &amp;#039;&amp;#039;&amp;#039;Ereigniserkennung&amp;#039;&amp;#039;&amp;#039; (I/O oder Signale),&lt;br /&gt;
* die &amp;#039;&amp;#039;&amp;#039;Ereignisverteilung&amp;#039;&amp;#039;&amp;#039;, und&lt;br /&gt;
* die &amp;#039;&amp;#039;&amp;#039;Ereignisverarbeitung&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
== Struktur ==&lt;br /&gt;
Typische Komponenten des Reactor-Musters:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Komponente !! Aufgabe&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;Handle&amp;#039;&amp;#039;&amp;#039; || Ein Deskriptor (z. B. Socket oder File-Handle), der Ereignisse erzeugen kann&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;Event Demultiplexer&amp;#039;&amp;#039;&amp;#039; || Wartet auf Ereignisse mehrerer Handles (z. B. mit &amp;lt;code&amp;gt;select()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;poll()&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;epoll()&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;Reactor&amp;#039;&amp;#039;&amp;#039; || Registriert Event-Handler und leitet eintreffende Ereignisse weiter&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;Event Handler&amp;#039;&amp;#039;&amp;#039; || Implementiert die Logik, die bei einem bestimmten Ereignis ausgeführt werden soll&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;Concrete Event Handler&amp;#039;&amp;#039;&amp;#039; || Konkrete Implementierung (z. B. ClientHandler, FileHandler)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Ablaufdiagramm ==&lt;br /&gt;
Typischer Kontrollfluss des Reactor-Musters:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
+---------------------+&lt;br /&gt;
|      Reactor        |&lt;br /&gt;
|---------------------|&lt;br /&gt;
| - Event-Loop        |&lt;br /&gt;
| - Demultiplexer     |&lt;br /&gt;
+---------+-----------+&lt;br /&gt;
          |&lt;br /&gt;
          v&lt;br /&gt;
  [Event tritt auf]&lt;br /&gt;
          |&lt;br /&gt;
          v&lt;br /&gt;
+---------------------+&lt;br /&gt;
|   Event Handler     |&lt;br /&gt;
|---------------------|&lt;br /&gt;
|  onRead(), onWrite()|&lt;br /&gt;
+---------------------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Beispiel (C++) ==&lt;br /&gt;
Ein einfaches Beispiel, wie ein Reactor mit &amp;lt;code&amp;gt;select()&amp;lt;/code&amp;gt; mehrere Sockets überwacht:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/socket.h&amp;gt;&lt;br /&gt;
#include &amp;lt;netinet/in.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
#include &amp;lt;algorithm&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class EventHandler {&lt;br /&gt;
public:&lt;br /&gt;
    virtual int getHandle() const = 0;&lt;br /&gt;
    virtual void handleEvent() = 0;&lt;br /&gt;
    virtual ~EventHandler() = default;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class ClientHandler : public EventHandler {&lt;br /&gt;
    int sockfd;&lt;br /&gt;
public:&lt;br /&gt;
    explicit ClientHandler(int fd) : sockfd(fd) {}&lt;br /&gt;
    int getHandle() const override { return sockfd; }&lt;br /&gt;
    void handleEvent() override {&lt;br /&gt;
        char buffer[256];&lt;br /&gt;
        int n = read(sockfd, buffer, sizeof(buffer) - 1);&lt;br /&gt;
        if (n &amp;gt; 0) {&lt;br /&gt;
            buffer[n] = &amp;#039;\0&amp;#039;;&lt;br /&gt;
            std::cout &amp;lt;&amp;lt; &amp;quot;Nachricht: &amp;quot; &amp;lt;&amp;lt; buffer &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
        }&lt;br /&gt;
        else {&lt;br /&gt;
            std::cout &amp;lt;&amp;lt; &amp;quot;Client getrennt.\n&amp;quot;;&lt;br /&gt;
            close(sockfd);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class Reactor {&lt;br /&gt;
    std::vector&amp;lt;EventHandler*&amp;gt; handlers;&lt;br /&gt;
public:&lt;br /&gt;
    void registerHandler(EventHandler* handler) {&lt;br /&gt;
        handlers.push_back(handler);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    void handleEvents() {&lt;br /&gt;
        while (true) {&lt;br /&gt;
            fd_set readfds;&lt;br /&gt;
            FD_ZERO(&amp;amp;readfds);&lt;br /&gt;
            int maxfd = 0;&lt;br /&gt;
&lt;br /&gt;
            for (auto* h : handlers) {&lt;br /&gt;
                FD_SET(h-&amp;gt;getHandle(), &amp;amp;readfds);&lt;br /&gt;
                maxfd = std::max(maxfd, h-&amp;gt;getHandle());&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            int ready = select(maxfd + 1, &amp;amp;readfds, nullptr, nullptr, nullptr);&lt;br /&gt;
            if (ready &amp;gt; 0) {&lt;br /&gt;
                for (auto* h : handlers)&lt;br /&gt;
                    if (FD_ISSET(h-&amp;gt;getHandle(), &amp;amp;readfds))&lt;br /&gt;
                        h-&amp;gt;handleEvent();&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Beispiel zeigt den Kernmechanismus:  &lt;br /&gt;
Der Reactor wartet mit &amp;lt;code&amp;gt;select()&amp;lt;/code&amp;gt; auf Ereignisse und ruft dann den passenden Handler auf.&lt;br /&gt;
&lt;br /&gt;
== Vorteile ==&lt;br /&gt;
* Hohe Effizienz bei vielen gleichzeitigen Verbindungen (non-blocking I/O)  &lt;br /&gt;
* Klare Trennung von Ereigniserkennung und -verarbeitung  &lt;br /&gt;
* Erweiterbar um neue Ereignistypen durch neue Handler  &lt;br /&gt;
&lt;br /&gt;
== Nachteile ==&lt;br /&gt;
* Erhöhter Programmieraufwand  &lt;br /&gt;
* Komplexere Fehlerbehandlung  &lt;br /&gt;
* Nicht ideal für CPU-lastige Aufgaben (dafür eignet sich das [[Proactor-Entwurfsmuster]])&lt;br /&gt;
&lt;br /&gt;
== Vergleich: Reactor vs. Proactor ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Merkmal !! Reactor !! Proactor&lt;br /&gt;
|-&lt;br /&gt;
| Auslöseart || Ereignis (z. B. &amp;quot;Daten sind verfügbar&amp;quot;) || Abschluss (z. B. &amp;quot;Lesevorgang ist beendet&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| Typischer Einsatz || Non-blocking I/O || Asynchronous I/O&lt;br /&gt;
|-&lt;br /&gt;
| Steuerung || Anwendung reagiert aktiv auf Ereignisse || Betriebssystem meldet fertige Operationen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* [[Proactor-Entwurfsmuster]]&lt;br /&gt;
* [[Observer-Entwurfsmuster]]&lt;br /&gt;
* [[Event-Driven Architecture]]&lt;br /&gt;
* [[select() (C)]]&lt;br /&gt;
* [[epoll() (Linux)]]&lt;br /&gt;
* [[Socket (Informatik)]]&lt;br /&gt;
&lt;br /&gt;
== Quellen ==&lt;br /&gt;
* Douglas C. Schmidt: *Reactor: An Object Behavioral Pattern for Demultiplexing and Dispatching Handles for Synchronous Events*  &lt;br /&gt;
* POSA2 – *Pattern-Oriented Software Architecture: Patterns for Concurrent and Networked Objects*  &lt;br /&gt;
* [https://en.wikipedia.org/wiki/Reactor_pattern Wikipedia: Reactor Pattern]&lt;br /&gt;
* [https://man7.org/linux/man-pages/man2/select.2.html select(2) Manpage]&lt;/div&gt;</summary>
		<author><name>PhilKa</name></author>
	</entry>
</feed>