PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : 2 while(true)-Schleifen parallel in perl



AceTheFace
16-03-2004, 08:21
Hi,

bin am schreiben eines kleinen IRC-Bots.
Um auf irgendwelche Worte/Befehle aus dem Chat reagieren zu können, muss er ja ständig den Chat überwachen. Dies geschieht in einer while(true)-Schleife:

while($line =<$sock>){ print $line; }

Nun soll der Bot aber gleichzeitig noch einen xmms-player überwachen und sobald sich das Lied ändert das neue Lied im IRC posten. Schreibe ich die XMMS-Überwachungsmethode in obige while-Schleife rein, dann prüft der nat. nur ob ein neues Lied kommt, wenn was über den Socket reinkommt, sprich, wenn was im chat geschrieben wird.
Diese Überwachungsmethode sollte also irgendwie in eine zweite While-SChleife, die parallel zu ersten auch immer abgearbeitet wird. In java oder so könnte man das ja mit Threads realisieren, aber wie mache ich sowas in perl?

Gruß und danke,

Ace

peschmae
16-03-2004, 10:17
Wieso nicht einfach zwei unabhängige Scripts? Bzw. ein Script mit Optionen das du dann zweimal startest? Also zwei prozesse.
Die Dinger haben ja absolut nix miteinander zu tun.

MfG Peschmä

AceTheFace
16-03-2004, 10:33
Original geschrieben von peschmae
Wieso nicht einfach zwei unabhängige Scripts? Bzw. ein Script mit Optionen das du dann zweimal startest? Also zwei prozesse.
Die Dinger haben ja absolut nix miteinander zu tun.

MfG Peschmä

Aber dann kann ich ja nicht auf den gleichen Socket zugreifen, oder?

Gruß,

Ace

peschmae
16-03-2004, 12:33
Hehe. Ok. :)

Perl kann schon Threads, auch wenn sich das offenbar in den letzten paar Versionen ständig geändert hat und noch nicht perfekt ist.

Man kann offenbar Perl für mit oder ohne Multi-Threading erstellen.

Keine Ahnung. Wirklich nicht.

MfG Peschmä

sticky bit
16-03-2004, 15:00
fork() sollte helfen...

peschmae
16-03-2004, 16:21
das macht aber zwei Prozesse draus. Oder ist das in Perl was anderes?
Hast du ein bisschen Doku dazu? Ich hab nämlich nix gefunden.

MfG Peschmä

sticky bit
16-03-2004, 17:12
Jupp, zweigt einen Child-Prozess ab. Aber dass wäre ja eigentlich doch das richtige, zwei Prozesse, zwei parallel laufende Schleifen auf dem selben Socket weil der Handle dazu in beiden Prozessen identisch ist sofern er nicht nach dem fork() verändert wird...

Dokumässig hab ich grad nichts parat, ich guck aber mal...

peschmae
16-03-2004, 17:44
Nein. Weil aus Sockets kann man dieselben Daten doch nur einmal lesen. Oder bringe ich da was durcheinander?

Das ist ja genau der Grund wieso mein Vorschlag - zwei Prozesse - nicht gehen kann.

Hmm. Zwar. Der zweite Prozess muss ja nur ab und zu mal schreiben. :)

MfG Peschmä

sticky bit
17-03-2004, 08:37
Original geschrieben von peschmae
Nein. Weil aus Sockets kann man dieselben Daten doch nur einmal lesen
Hmm, OK, das ist ein Argument, dann müsstest du buffern und... Naja, kompliziert IMHO.
Schon mal überlegt ob es mit nen "Nonblocking" Socket gehen würde beides in eine Schleife zu packen?
Äh, bevor du nach Doku fragst ( ;) ), guck mal bei sourceforge nach dem perlchat project die scheinen sowas zu verwenden, allerdings steig ich da nich ganz durch, aber vielleicht hilfts dir?

fork
17-03-2004, 17:10
Also gemaess der Bibel(Programmieren mit Perl) habe ich mal folgendes Beispiel mit Threads. Das Beispiel funktioniert nicht, da die Variablen nicht (wie in der Doku beschrieben) gemeinsam für alle Threads die selben Werte benutzen. Vielleicht ist die Perl Version von SuSE 9.0 nicht multithreaded kompiliert(... was aber nach den Verzeichnisnamen wieder irgendwie nicht so scheint).

Die Lockfunktionen sperren gleichzeitigen Zugriff auf Variablen(Advisory Locks) um die Schreiblesevorgänge abzusichern; bis zum Ende des aktuellen Blocks.

#!/usr/bin/perl

use strict;
use diagnostics;
use warnings;

use Thread;

# --- Prog

my $thread_1 = Thread->new( \&chatterbox );
my $thread_2 = Thread->new( \&songcheck );

# --- gelangweiltes Hauptprogramm
while(1) {
{
lock $song;
print "Main: $song\n";
}
sleep 1;
}

# --- chatter

sub chatterbox {
while (1) {
{
lock $song;
print "Song: $song Text: Das was vom Port kommt\n";
}
sleep 1;
}

}

# --- songcheck

sub songcheck {
while(1) {
{
lock $song;
$song=&getnewsong();
print ("My song is $song\n");
}
sleep 3;
}
}

AceTheFace
18-03-2004, 08:43
Danke, wenn ich mein Vordiplom in der Tasche hab, werde ich das mal ausprobieren ;)

Gruß,

Ace