Schrift
[thread]11510[/thread]

Multitasking mit Perl

Leser: 3


<< >> 8 Einträge, 1 Seite
blue-dev
 2008-03-22 17:50
#107370 #107370
User since
2008-03-22
4 Artikel
BenutzerIn
[default_avatar]
Hallo,
ich bin noch ein neuling was Programmieren mit Perl angeht, und stehe vor folgendem Problem:

Ich will als Einstieg einen kleinen Chat schreiben um mich mit der Abstraktion von Client und Server unter Perl vertraut zu machen.
Den Server habe ich bereits fertig und er gibt auch bereits Chat messages zurück und kann welche empfangen, aber wie bekomme ich Perl dazu das man gleichzeitig über <STDIN> etwas schreiben kann, und neue Nachrichten bekommt, also Perl zwei Aktionen gleichzeitig macht?

Mein Code bis jetzt:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
use communication;
use strict;

my $communication = communication->new;
my $input = "welcome";

while ($input ne "exit") {
        $communication->getNew();
        $communication->message($input);
        print "->";
        $input = <STDIN>;
        chomp($input);
}


Mit der Methode getNew() überprüft er ob neue Nachrichten auf dem Server sind, diese müsste also jedes Sekunde einmal im Hintergrund ausgeführt werden, aber gleichzeitig müsste ich (halt wie bei einem Chat) auch etwas schreiben können.
Wie geht das mit Perl?
murphy
 2008-03-23 00:41
#107385 #107385
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
Um das zu erreichen gibt es mehrere Möglichkeiten: Zum einen könntest Du mehrere Threads verwenden um tatsächlich parallel mit beiden Datenquellen zu arbeiten. Bei dieser Variante musst Du aber die beiden parallel laufenden Codeteile über irgendeine Datenstruktur, zum Beispiel eine Warteschlange für Nachrichten, synchronisieren.

Zum anderen könntest Du zwischen den Eingabendatenkanälen von der Konsole und vom Chatpartner mittels -f select multiplexen. In diesem Fall musst Du aber wohl Deine Schnittstelle etwas verändern, da der Codeteil, der das Multiplexen übernimmt, unmittelbaren Zugang zu allen Dateihandles braucht, von denen gelesen werden soll.
When C++ is your hammer, every problem looks like your thumb.
sid burn
 2008-03-23 03:21
#107388 #107388
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
Generell gibt es drei Möglichkeiten um Multitasking zu erreichen. Thread, Forking und Multiplexing.
Alle drei haben Ihre Vor/Nachteile.

Forking ist wohl das urgestein. Mit fork() clonst du du deinen aktuellen Prozess der an der selben stelle fortfährt wo du fork() aufgerufen hast.

Mit Threading erstellst du mehrere Arbeitende Threads innerhlab eines Prozesses.

Und mit Multiplexing schaust du das deine Applikation nirgendswo im Blocking gerät, oder besser gesagt nur ein kontrolliertes blocking. Und dann nur wenn etwas vorhanden ist deine Applikation etwas tut. select() wie murphy sagte ich hier der Schlüssel, obwohl ich hier eher IO::Select empfehlen würde. Das ist deutlich einfacher.


Forking:
Vorteile:
- Ich würde es als einfach in der Programmierung betrachten. Du musst wenig beachten dafür.

Nachteile:
- Die Kommunikation unterhalb der Prozesse ist etwas schwieriger.
- In der Regel verbraucht es mehr Speicher und ist etwas langsamer als Threading.
- Funktioniert unter GNU/Linux, BSD, Unix sehr gut, alelrdiengs nicht unter Windows.


Threading:
Vorteile:
- Schneller und weniger Speicherverbrauch als Forking
- Leichtere Kommunikation, und Datenaustausch da alle Threads auf die selben Daten zugreifen können.

Nachteile:
- komplexer in der Programmierung da durch den gemeinsamen Datenaustausch schwer zu findende Fehler auftreten können. Sogenannte Race Condition die von der Reihenfolge der Ausführung abhängt. Um diese art von Fehler zu vermeiden musst du den Zugriff auf Variablen/Ressourcen locken. Dieses entfällt bei Forking.
- Durch den ersten nachteil ist somit nicht jede Bibliothek ist Threadsicher. Bibliotheken müssen extra Programmiert werden damit sie Threadsicher sind. Auch dies entfällt bei Forking.
- In Perl ist Threadsupport so lala eingebaut. Zwar ist der neue Moderne Threadsupport besser als der alte, allerdiengs ist dieser immer noch anders als man es eigentlich von Threading erwartet.


Multiplexing:
Vorteile:
- Ist in der Regel am platformunabhängigsten.
- Sollte wohl weniger Ressourcen, Speicher als Threading verbrauchen.

Nachteile:
- Erfordert den größten aufwand in der Programmierung.
- Multiplexing regelt nur das zu keinem Zeitpunkt I/O Blockt so das ein gefühl für Multitasking entsteht. Oft ist es auch das was man möchte, z.B. bei Servern. Allerdiengs wenn du etwas anderes machen möchtest ist Multiplexing eventuell dafür nicht geeignet.
- Threading oder Forking sollten Performanter sein.


EDIT:
Ach ganz vergessen. Bei solchen Sachen solltest du dir Eventuell mal POE anschauen. Das ist genau für solche Sachen gedacht und ist praktisch die vierte Möglichkeit. ;)

http://poe.perl.org/



Hmm für forking weiß ich derzeit gar nicht was man da für offene Doku gibt. Zumindest kenne ich das Buch "Netzwerkprogrammierung mit Perl" das sich komplett um Multitasking dreht. Dort wird auch fork() genauer erklärt und auf was es generell alles zu beachten gibt.

Eventuell kann dir auch http://perldoc.perl.org/perlipc.html helfen.
Dieses hier ist nur Interessant für Systeme die kein fork() als Systemaufruf besitzen. z.B. Windows: http://perldoc.perl.org/perlfork.html

Für Threading gibt es:
http://perldoc.perl.org/perlthrtut.html
http://perldoc.perl.org/threads.html

Für Multiplexing wüste ich ebenfalls wenig Doku. Nur dieses hier was etwas knapp ist.
http://perldoc.perl.org/IO/Select.html



Aber eins frage ich mich die ganze Zeit dann doch:
Quote
Ich will als Einstieg einen kleinen Chat schreiben um mich mit der Abstraktion von Client und Server unter Perl vertraut zu machen.
Den Server habe ich bereits fertig und er gibt auch bereits Chat messages zurück und kann welche empfangen, aber wie bekomme ich Perl dazu das man gleichzeitig über <STDIN> etwas schreiben kann, und neue Nachrichten bekommt, also Perl zwei Aktionen gleichzeitig macht?

Wie kann dein Server schon fertig sein wenn du nicht weißt wie du zwei Aktionen gleichzeitig ausführen kannst, bzw du generell nichts von Multitasking weißt? So ein Chat Server basiert doch dadrauf das du mehrere Verbindungen mit Clients aufbauen musst und mehrere Dinge gleichzeitig machst. Gerade der Server müsste voll von einen der oben genannten Techniken sein.


Btw:
Code: (dl )
use communication;

Du solltest dein modul in "Communication" abändern. (Großes C am anfang). Module in komplett kleinbuchstaben sind für Perl Reserviert.
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
blue-dev
 2008-03-23 15:19
#107397 #107397
User since
2008-03-22
4 Artikel
BenutzerIn
[default_avatar]
Erstmal danke für deine Hilfe!
Ich werde mir alle Methoden angucken und dann nochmal Feedback geben welche am besten funktioniert hat.

sid burn+2008-03-23 02:21:08--
Aber eins frage ich mich die ganze Zeit dann doch:
Wie kann dein Server schon fertig sein wenn du nicht weißt wie du zwei Aktionen gleichzeitig ausführen kannst, bzw du generell nichts von Multitasking weißt? So ein Chat Server basiert doch dadrauf das du mehrere Verbindungen mit Clients aufbauen musst und mehrere Dinge gleichzeitig machst. Gerade der Server müsste voll von einen der oben genannten Techniken sein.


Der Server ist nicht in Perl geschrieben sondern in PHP. Da hab ich eine ganze Menge Erfahrung.
Perl ruft über libwww einfach eine URL auf und übergibt einen String oder nicht, der Server speichert ihn dann entweder in der Datenbank, oder gibt alle gesendeten String die nach dem letzten Request der IP kamen zurück. Alles im XML Format so das ich das einfach bearbeiten kann.
Multitasking in PHP gibt es eigentlich nicht, deswegen kenne ich da auch keine Stichwörter nach denen ich bei Perl hätte suchen können.
Pro Browser aufruf handelt Apache alle Prozesse usw, da brauche ich mir darum keine Sorgen zu machen.

Quote
Btw:
Code: (dl )
use communication;

Du solltest dein modul in "Communication" abändern. (Großes C am anfang). Module in komplett kleinbuchstaben sind für Perl Reserviert.


Achso, ich hab mich schon gewundert warum alle Module die ich auch cpan gefunden habe Großbuchstaben haben. Bei PHP und C++ ist es ja eher der standard Klassen und Funktionen klein zu schreiben solange sie aus einem Wort bestehen.
ptk
 2008-03-23 20:01
#107406 #107406
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
sid burn+2008-03-23 02:21:08--
Threading:
Vorteile:
- Schneller und weniger Speicherverbrauch als Forking
In der Theorie sollte der Speicherverbrauch geringer sein. In der Praxis müssen bei Perl große Teile des Interpreters geclonet werden, so dasss ich den geringeren Speicherverbrauch nicht unterschreiben möchte.

Schneller: was meinst du damit genau? Meinst du, dass es schneller ist, einen neuen Thread zu erzeugen als zu forken? Bei früheren Experimenten mit perl5.8.x und FreeBSD habe ich den gegenteiligen Eindruck gewonnen (kann sein, dass es mit perl5.8.8 und moderneren FreeBSD-Versionen besser ist).

Außerdem muss man beachten, dass ein perl, bei dem Threads eingebaut sind, generell um einige Prozent langsamer ist als ein unthreaded perl. Auch wenn man gar keine Threads verwendet.

Quote
- Leichtere Kommunikation, und Datenaustausch da alle Threads auf die selben Daten zugreifen können.
Leider gibt es bei ernstzunehmenden Datenstrukturen (tiefe Datenstrukturen, Objekte) noch immer Probleme mit threads::shared.
Quote
Nachteile:
- komplexer in der Programmierung da durch den gemeinsamen Datenaustausch schwer zu findende Fehler auftreten können. Sogenannte Race Condition die von der Reihenfolge der Ausführung abhängt. Um diese art von Fehler zu vermeiden musst du den Zugriff auf Variablen/Ressourcen locken. Dieses entfällt bei Forking.
- Durch den ersten nachteil ist somit nicht jede Bibliothek ist Threadsicher. Bibliotheken müssen extra Programmiert werden damit sie Threadsicher sind. Auch dies entfällt bei Forking.
- In Perl ist Threadsupport so lala eingebaut. Zwar ist der neue Moderne Threadsupport besser als der alte, allerdiengs ist dieser immer noch anders als man es eigentlich von Threading erwartet.
Man muss auch beachten, dass nicht jedes vom Betriebssystem ausgelieferte perl Thread-Unterstützung haben muss.
blue-dev
 2008-03-23 20:40
#107408 #107408
User since
2008-03-22
4 Artikel
BenutzerIn
[default_avatar]
Also was mich sehr angesprochen hat war Möglichkeit 4).
Da habe ich allerdings noch eine Frage zu:
Auf der Website steht folgendes:

Quote
A task that calls sleep() or something else that doesn't return for a while will pause the entire program. This will change when Perl's threads become mainstream.

Calling die() or exit() in one task will stop every task, and indeed the entire program. This may not be the desired effect. It will change when POE gets exceptions.


Wenn ich jetzt eine Session erstelle die die ganze Zeit <STDIN> oder readline anfragen aufnimmt, ist es nicht fast das selbe wie sleep? Der Prozess gibt ja nichts zurück solange ich nicht Enter drücke.
Oder hab ich da jetzt was falsch verstanden?
sid burn
 2008-03-23 21:01
#107410 #107410
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
Code: (dl )
1
2
Wenn ich jetzt eine Session erstelle die die ganze Zeit <STDIN> oder readline anfragen aufnimmt, ist es nicht fast das selbe wie sleep? Der Prozess gibt ja nichts zurück solange ich nicht Enter drücke.
Oder hab ich da jetzt was falsch verstanden

Im Grunde genommen ist das korrekt. Du musst schauen das dein Programm nirgendwo blockiert, sonst hängt alles und du hast kein Multitasking. Ich kann dir aber zu POE nicht viel erzählen. Habe nur mal die Grundlagen dazu gelesen.

Aber je nachdem was du genau mit <STDIN> machst soltle eigentlich IO::Select die Lösung sein. Das du nur dann etwas von <STDIN> liest wenn auch etwas vorhanden ist. Und somit nicht ins Blocken kommst. Genau das macht IO::Select. Allerdiengs ist POE ja ein Framework. Ich denke für Benutzereingaben und das nicht Blockierte Lesen müsste es bestimmt eine bessere Möglichkeit in POE geben.

Soweit wie ich Beispiele gesehen habe funktioniert das ganze ja sowieso event gesteuert. Sprich es kommt irgendwo ein Event z.B. "INPUT" und du schreibst dann eine Routine die dann bei diesem Event ausgeführt wird. Daher eigentlich müsste POE dir das alles abnehmen.

Aber wie gesagt ich kenne POE zu wenig um dir da genaues zu sagen wie es geht. Musst du mal die Beispiele durchschauen. Auf der POE webseite gibt es auch das "Cookbook" wo schon etliche Beispiele gezeigt werden. Eventuell findest du dort auch etwas in den Beispielen was deine Aufgabe löst.
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
Strat
 2008-03-28 12:46
#107590 #107590
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
der Artikel How to Write a Chat Server hat ein paar interessante Ideen...
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
<< >> 8 Einträge, 1 Seite



View all threads created 2008-03-22 17:50.