Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]10588[/thread]

Probleme mit forks.pm

Leser: 1


<< >> 10 Einträge, 1 Seite
SaschaTen
 2007-10-15 17:42
#100854 #100854
User since
2007-10-15
28 Artikel
BenutzerIn
[default_avatar]
Hallo ich hoffe ihr könnt mir weiterhelfen.

Ich habe ein Skript welches mit Hilfe von forks.pm mehrere Threads startet, diese laufen auch wunderbar parallel, teilen sich auch eine gemeinsame Variable und Änderungen werden auch zu den Anderen Threads durchgereicht.

Kurze Erklärung ich frage vorher die Verfügbarkeit einiges Rechner ab, die Rechner welche ich erreiche schreibe ich in ein Array, dieses Array teilen sich die Threads. Wenn ein Thread beginnt sperrt er dieses Array und holt sich einen Rechnernamen mit pop runter. Dann macht er seine Abfragen ist das Array leer sollte sich sich der Thread beenden.

Das ganze sollte ähnlich Laufen wie in diesem Testscript hier:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#!/usr/bin/perl

use strict;
use forks;
use forks::shared;

# "Gloabeles" Array als gemeinsame Variable angeben,
# somit teilen sich die Threads das Array
# statt sich eine Kopier im Adressraum anzulegen
my @stack : shared;
my $tempvar : shared;
   $tempvar = 10000;

for(my $i = 0; $i < 10000; $i++)
{
  $stack[$i] = $i;
}
my $thread1 = threads->new(\&echo, 1);
my $thread2 = threads->new(\&echo, 2);
my $thread3 = threads->new(\&echo, 3);
my $thread4 = threads->new(\&echo, 4);
$thread1->join();
$thread2->join();
$thread3->join();
$thread4->join();
print "threads erstellt!\n";

sub echo
{
  # Name des Threads
  my $thread = $_[0];
  my $temp="";
  do
  {
    # sichert das Array vor dem Zugriff des anderen Threads
    lock @stack;
    # holt sich den letzten Wert aus dem Array
    $temp = pop(@stack);
    $tempvar-= $temp;
    # aus gabe des Threads
    open(LOG, ">>thread.log");
    print "Thead ".$thread." print ".$temp." uebersprungen".$tempvar."\n";
    print LOG $temp."\n";
    close(LOG);
    $tempvar = $temp;
    # schickt den Thread erst mal schlafen
  }
  while($temp >=4)
}



Mit dem Testscript funktioniert es, mit meinem Richtigen leider nicht!
Hatrtet ihr auch schon mal das Problem das sich die Threads mit froks.pm nicht geschlossen haben? und wenn ja wie habt ihr das Probleme gelöst?

Das komische ist, wenn ich mein Skript starte sind sofort 2 Skripts da, obwohl normal noch kein Thread laufen dürft!
Nach nochmaligen prüfen denke ich das es Probleme mit dem 2. Skript gibt das sich dieses nicht sauber beendet, da die Threads nach ihrem Durchlauf weg sind und via ps aux nicht mehr zu finden sind!

Danke für eure Hilfe schon mal im vorraus!
-----------
Wer Rechstschreibfehler findet, darf diese behalten und bei Ebay versteigern!!!
-----------
Nidar mied där Rächtschraibunk!!!
weismat
 2007-10-15 20:45
#100867 #100867
User since
2003-08-18
142 Artikel
BenutzerIn
[default_avatar]
Erstmal würde ich normale Threads nehmen und nicht fork.
Bei normalen Threads würde ich für das Arbeiten mit Arrays immer auf CPAN:Thread::Queue zurückgreifen.
Die sehr kurze Implementierung von diesem Modul ist sehr lehrreich, wenn man mal wieder mit Threads arbeitet und sich die Zusammenhänge anschauen will.
Man hat so leicht Fehler in der Synchronisation gemacht und das macht dann alles das Modul.
SaschaTen
 2007-10-15 23:29
#100881 #100881
User since
2007-10-15
28 Artikel
BenutzerIn
[default_avatar]
Danke für den Tip.
Ich hatte es schon mal mit Threads versucht da wollte das Skript leider nicht ganz so gut laufen... immer ist der erste Thread gelaufen und die anderen kamen nicht zum Zug.
Nun nach deinem Tip habe ich das Skript von Grund auf neu geschrieben, und es mit Threads.
Die queue habe ich nocch nicht eingebaut. aber das tue ich Morgen gleich.
Muß icch diie Queue auch als shared kennzeichnen oder ist sie das automatisch?
-----------
Wer Rechstschreibfehler findet, darf diese behalten und bei Ebay versteigern!!!
-----------
Nidar mied där Rächtschraibunk!!!
weismat
 2007-10-16 09:13
#100897 #100897
User since
2003-08-18
142 Artikel
BenutzerIn
[default_avatar]
Die Queue ist automatisch shared. Die Methoden sind thread-sicher.
Wenn Du anfängst mit Threads zu arbeiten, würde ich erstmal die Kommunikation zwischen den Threads mit Queues realisieren, je nachdem welches Thread-Pattern Du implementierst.
SaschaTen
 2007-10-17 15:10
#100971 #100971
User since
2007-10-15
28 Artikel
BenutzerIn
[default_avatar]
Kann man in einer Thread::Queue auch Instanzen einer Klasse oder andere komplexe Objekte speichern?

ich bekomme Folgende Ausgabe:
Invalid value for shared scalar at /usr/lib/perl5/5.8.8/Thread/Queue.pm line 90.

Kann aber nichts damit anfangen, weil ich an der Queue.pm nichts gemacht habe.
Ich habe auch schon versucht nur die Referenz auf ein Objekt zu speichern mit dem selben Ergebnis.
-----------
Wer Rechstschreibfehler findet, darf diese behalten und bei Ebay versteigern!!!
-----------
Nidar mied där Rächtschraibunk!!!
weismat
 2007-10-17 16:02
#100981 #100981
User since
2003-08-18
142 Artikel
BenutzerIn
[default_avatar]
Leider kannst Du allgemein keine Objekte zwischen Threads austauschen - nur Skalare, Arrays und Hashes :-(
SaschaTen
 2007-10-17 16:10
#100982 #100982
User since
2007-10-15
28 Artikel
BenutzerIn
[default_avatar]
Gibt es ne möglichkeit das ganze zu umgehen?
Ich ahbe das Problem wenn ich jetzt den inhalt des Objektes in die Threadque als Array schreibe, kommen die am ende nicht als Array sondern als Skalar raus. Somit ist nicht mehr gewährleistet dasdie einzelnen Attribute im richtigen Objekt landen.
Es würde sicherlich auch nischt bringen ein Hash aus Objekten zu bauen oder?
-----------
Wer Rechstschreibfehler findet, darf diese behalten und bei Ebay versteigern!!!
-----------
Nidar mied där Rächtschraibunk!!!
weismat
 2007-10-17 16:37
#100983 #100983
User since
2003-08-18
142 Artikel
BenutzerIn
[default_avatar]
Du koenntest Deine Objekte serialisieren - das ist das einzige Moeglichkeit...
Es sind allgemeine keine Referenzen fuer shares zulaessig, nur die elementaren Datentypen.
SaschaTen
 2007-10-17 17:25
#100985 #100985
User since
2007-10-15
28 Artikel
BenutzerIn
[default_avatar]
ok habe es jetzt umständlich gemacht :)
Habe die Attribute der Klasse in ein String gepackt und mit ":" getrennt... naja im Thread erstelle ich dann wieder ne neue Instanz mit split() kann ich ja die einzelnen Attribute wieder Trennen.
Einfach, aber obs Effektivist weiß ich net!
-----------
Wer Rechstschreibfehler findet, darf diese behalten und bei Ebay versteigern!!!
-----------
Nidar mied där Rächtschraibunk!!!
renee
 2007-10-17 17:26
#100986 #100986
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Du könntest ja auch mit CPAN:JSON serialisieren...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
<< >> 10 Einträge, 1 Seite



View all threads created 2007-10-15 17:42.