Schrift
[thread]6222[/thread]

bei langen Subroutinen bleibt alles stehen: - Nebenläufigkeit mit fork()? -



<< >> 3 Einträge, 1 Seite
anti
 2004-04-28 20:38
#81898 #81898
User since
2003-11-29
155 Artikel
BenutzerIn
[default_avatar]
Hi Community,
ich habe ein kleines Problem:
Ich habe eine GUI gebastelt, aus der heraus beim Klick auf einen bestimmten Button eine Subroutine / evtl. auch anderes Perlskript aufgerufen werden soll. Das Problem dabei ist, dass die Subroutine / anderes Skript sehr lange (ca. 2min) rechnet. In dieser Zeit friert die GUI komplett ein, d.h. es ist nichts mehr auswählbar oder so.
Also dachte ich mir, ich "erschaffe" einfach einen Child-Prozess, und der übernimmt die Subroutine /anderes Skript. Das ganze sieht ungefähr so aus:
Code: (dl )
1
2
3
4
5
6
7
8
my $child = fork(); 
if ($child == '0') {
exec('perl test.pl');
}else {while(!waitpid ($child,WNOHANG)) {
   #hier kann alles mögliche parallel weiterlaufen!!
   }
   print "\07fertig\n";
   }
Das ganze funktioniert in soweit, dass die GUI nun während der Berechnung der Subroutine "benutzbar" bleibt, allerdings bekomme ich keinerlei Rückmeldung wann fertig gerechnet wurde und auch Parameter kann ich so nicht übergeben. Dabei gilt noch zu bemerken, dass dieses Codestück in einem extra Skript steht und aus der GUI aufgerufen wird, da es, wenn ich es direkt in die GUI schreibe, abbricht (Windows beendet mit einer Fehlermeldung).
Gibt s nun eine Möglichkeit dieses Einfrieren ohne fork() zu verhindern - oder zumindest eine Rückmeldung zu erhalten, wann fertig gerechnet wurde?

Danke, Anti\n\n

<!--EDIT|anti|1083170308-->
ptk
 2004-04-28 21:00
#81899 #81899
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
Variablen, die zur Zeit des forks definiert sind, sind auch im neuen Prozess sichtbar. Somit kannst du auf einfache Weise Parameter uebergeben. Beim Verwenden von fork() muss man (mindestens bei Tk, aber wahrscheinlich auch bei anderen Toolkits) darauf achten, dass man den Kindprozess mit CORE::exit() und nicht mit exit() beendet. Wegen eines Bugs in Tk 804.026 muss man sogar POSIX::_exit() verwenden, aber dieser Bug ist in Tk 804.027 behoben.

Du koenntest auch ueberlegen, ob du aus deinem Skript ein hybrides Skript/Modul machst, dann kannst du es auch per require einbinden und hast mit Parameteruebergabe etc. weniger Probleme.

Wenn du weitere Ergebnisse zurueck an den Vaterprozess schicken willst, musst du eine pipe() aufmachen und die Ausgabe per fileevent() einsammeln.

Es lohnt sich vielleicht auch, in das Modul Tk::ExecuteCommand (-> CPAN) zu schauen.
Gast Gast
 2004-04-29 23:07
#81900 #81900
Danke!
Es klappt soweit schon ganz gut, allerdings ist dieses Prozesshandling / IPC ziemlich schwer zu durchsteigen (und z.T. auf WIN32 - Systemen nur ausreichend implementiert).

Greetz, Anti
<< >> 3 Einträge, 1 Seite



View all threads created 2004-04-28 20:38.