Etwas Pipe-Ähnliches zur Prozesskommunikation

Status
Nicht offen für weitere Antworten.

schoppenhauer_entfernt_

Bekanntes Mitglied
Grüß Gott.

Ich hätte eine Frage, und zwar...

Ich möchte einige Threads, die mehr oder weniger nichts direkt miteinander zu tun haben (und damit schwierig bis unmöglich zu vereinigen sind), miteinander kommunizieren lassen, und zwar am b esten über irgendetwas pipe-ähnliches, z.B. einen Input- und einen Output-Stream, die irgendwie aneinander gekoppelt sind.
Momentan geht ebendies per loopback. Ich würde es aber sehr gerne ohne Netzwerkbeteiligung machen.

Geht das irgendwie?
 

schoppenhauer_entfernt_

Bekanntes Mitglied
Danke.
Ich hoffe mal, dass das auch geht.
Aber eine Frage hab ich noch: Ist es ein Problem, wenn mehrere PipedInputStreams vom gleichen PipedOutputStream lesen?
 

André Uhres

Top Contributor
Ein PipedOutputStream kann an einen PipedInputStream gebunden werden um eine Kommunikationspipe zu bilden. Der PipedOutputStream ist das sendende Ende der Pipe. Die Daten werden von einem Thread an das PipedOutputStream Objekt geschrieben und von einem anderen Thread aus dem angebundenen PipedInputStream ausgelesen.
 

schoppenhauer_entfernt_

Bekanntes Mitglied
Ok. Aber es könnte ja sein, dass ich zwei Threads habe, die einfach dasselbe bekommen sollen (bzw. es ist auch so, denn sonst hätte ich es nicht gefragt). Die sollen nix zurücksenden können, sondern einfach nur dasselbe empfangen. Kann man das?
 

André Uhres

Top Contributor
Du könntest es vielleicht mit einem Verteilerthread versuchen, der die Daten ausliest und an weitere Pipes verteilt.
 

Murray

Top Contributor
Wenn es nicht unbedingt Streams sein müssen, ist für so eine "one-to-many"-Kommunikation auch Observer/Observable eine gute Lösung. Ansonsten brauchst Du wohl eine verteilende Instanz (so eine Art DelegatingPipedOutputStream), die die hineingeschriebenden Bytes n-mal an die n InputStreams weiterleitet. Soweit ich weiss, gibt es da im JDK aber nichts vorgefertigtes.
 

schoppenhauer_entfernt_

Bekanntes Mitglied
Hm. Ok. Ein Problem hab ich doch noch - also bzw. das hab ich momentan noch nicht, aber es könnte auftreten (ehrlich!).

Wenn ich das so mache, dann kann es sein, dass einer der beiden Threads, an den ich sende, nicht weiterliest, sondern sehr lange auf sich warten lässt. Dann wird der Puffer des einen OutputStreams meines Verteilungsthreads voll sein, und die send-anweisung wird den gesamten Thread blockieren, während der andere Thread ggf. wartet.

Also ich hab mir da zwei Lösungen ausgedacht:

1. Jeder Thread hat auch gleichzeitig noch einen Pipe in die andere Richtung, der quasi sagt "sende mir jetzt so und so viele Bytes, ich kann das verkraften" - heißt, der thread "sagt", wie viel er braucht

2. Ich bastle selber einen beliebig vergrößerbaren Puffer
Das mit dem beliebig vergrößerbaren Puffer ist aber ein Problem. Denn ich verstehe nicht so ganz, wie ich feststellen kann, ob ein Puffer überhaupt voll ist. Bei InputStreams scheint das einfach zu gehen per in==out oder so.

Gibt es ne andere (ggf. bessere) Möglichkeit? Wenn nicht, welche der Beiden ist besser? Bzw. beide Möglichkeiten sind prinzipiell die Gleichen, ich brauche auf jeden Fall einen beliebig vergrößerbaren Puffer.
 

schoppenhauer_entfernt_

Bekanntes Mitglied
Murray hat gesagt.:
Die Verteiler-Instanz könnte für jeden Kanal einen eigenen Thread verwenden.
Da kapier ich jetzt nicht so ganz, was du meinst. Sorry.

Also wenn ich das richtig verstehe, soll ich quasi noch zu jedem der zwei PipedOutputStreams einen eigenen Thread "Dazwischen" schalten, der sich um die Puffer kümmert, richtig?
Aber bzw... das kann ich ja dann gleich im Verteilungsthread selber machen.
 

Murray

Top Contributor
Ist der "Verteilungsthread" derjenige, der die Daten produziert? Der verwendet dann doch irgendeine Instanz, die die Daten dann auf die verschiedene (Piped)OutputStreams verteilt. Die würde doch vereinfacht in etwa so aussehen:

Code:
public class DispatchingrOutputStream extends OutputStream() {

  private ArrayList<PipedOutputStream> targets;

  /* ... */

  public void write ( int b) throws IOException {
     for ( PipedOutputStream target : targets) {
       target.write( b);
     }
  }
}

Wenn ich das richtig verstanden habe, befürchtest Du jetzt, dass einer der verbundenen PipedInputStream nicht schnell genug ausgelesen werden kann und die auf diesen Stream schreibende write-Methode daher blockiert, sobald der Puffer des InputStreams voll ist. Damit würde die Schleife nicht weiter abgearbeitet, so dass die anderen Streams nicht mehr bedient werden; ausserdem kehrt die gesamte write Methode dann nicht zurück, bevor nicht alle Daten geschrieben werden konnten. Damit würde ein einziger langsamer Consumer-Thread den Producer blockieren.
Wenn man das vermeiden will, dann müsste für jedes Target ein eigener Thread verwendet werden.
Das könnte in etwa so aussehen (nur so runtergeschrieben und nicht zur Übersetzung empfohlen):

Code:
public class DispatchingrOutputStream extends OutputStream() {

  class Target implements Runnable {

     private Thread t;
     private PipedOutputStream targetStream;
     private int data;

     public Target( PipedOutputStream targetStream) {
       this.targetStream = targetStream;
       t = new Thread( this).start();
     }

     public void run() {
        while ( true) {
          synchronized( this) {
            wait();
          }
          target.write( data);
       }
     }

     public synchronized void write( int b) throws IOException {
        data = b;
        notify();
     }
  }

  private ArrayList<Target> targets;

  /* ... */

  public void write ( int b) throws IOException {
     for ( Target target : targets) {
       target.write( b);
     }
  }
}

/EDIT: Oops, das war zu früh abgeschickt.

Wenn jetzt Targets eben nicht nur das eine zu schreibende Byte speichern, sondern ihren eigenen Puffer verwalten, dann kannst Du diesen Puffer eben auch dynamisch verändern.
 

schoppenhauer_entfernt_

Bekanntes Mitglied
Ok.

Auch wenn ich den unteren Code nicht wirklich (bzw. eigentlich garnicht) verstehe, danke. Ich hoffe, wenn ich mir das noch etwas länger anschaue, wirds mir hoffentlich klarer.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
berserkerdq2 run-methode eines Threads so programmieren, dass 30x die Sekunde etwas ausgeführt wird. Allgemeine Java-Themen 44
W Methodenpointer...oder etwas Vergleichbares? Allgemeine Java-Themen 12
W Collections Suche etwas Sorted-List-Artiges...hat jemand eine Idee? Allgemeine Java-Themen 13
N Gibt es etwas allgemeineres as Object? Allgemeine Java-Themen 16
M Problem mit (etwas komplizierterem) Java Programm Allgemeine Java-Themen 14
T "Java lernen" in etwas mehr als 8 Tagen Allgemeine Java-Themen 13
J Zweiter Prozess der alle x Sekunden etwas abfragen soll Allgemeine Java-Themen 2
G Bringt es etwas System.gc() nach großen Aufgaben aufzurufen? Allgemeine Java-Themen 2
E Gibt es so etwas wie einen Windows Listener? Allgemeine Java-Themen 6
F Generics: spricht etwas dagegen raw types zu verwenden? Allgemeine Java-Themen 31
U if Abfrage macht etwas falsch Allgemeine Java-Themen 2
E in einem Untermenü (Baltt) etwas speichern? Allgemeine Java-Themen 3
A Thema JAR-Erstellung (mal wieder) => etwas komplizierter Allgemeine Java-Themen 8
G Gibt es etwas ähnliches wie den ReadKey bei Pascal? Allgemeine Java-Themen 3
H [Array als Text?] bräuchte etwas hilfe bzw erklärung Allgemeine Java-Themen 5
M Etwas in der Art von JRun? Allgemeine Java-Themen 4
S ein taschenrechner, aber etwas anders. Allgemeine Java-Themen 2
H Wie stellt ein JTree fest, wo etwas eingehängt werden soll? Allgemeine Java-Themen 2
L Plugins in Java realisieren: Wie könnte man so etwas machen? Allgemeine Java-Themen 7
OnDemand String Split Pipe Allgemeine Java-Themen 2
R PIPE Kommunikation mit Prozess blockiert Allgemeine Java-Themen 0
F Bash Pipe benutzen Allgemeine Java-Themen 4
G Windows Pipe erzeugen Allgemeine Java-Themen 12
G Pipe zu Windows Programm Allgemeine Java-Themen 16
T Pipe-Funktion - Prozente falsch? Allgemeine Java-Themen 8

Ähnliche Java Themen

Neue Themen


Oben