linux-l: perl-tk / zu frueh gefreut

Steffen Dettmer steffen at dett.de
Fr Jan 11 13:16:18 CET 2002


* Tobias Schlottke wrote on Thu, Jan 10, 2002 at 13:55 +0100:
> On Thu, 10 Jan 2002, Steffen Dettmer wrote:
> 
> > Geht nicht system("sleep 100&");?
> 
> Nein und nein und nein. Was und vor allem
> wer tut etwas mit '&'?
> Richtig: Die shell
> Keine shell, kein Hintergrund. Oder startet Perl
> etwa klamm, leise und heimlig ne shell?

Wieso klamm heimlich? Ist dokumentiertes Verhalten:

man perlfunc:

system PROGRAM LIST
[...]
	If there is only one scalar
	argument, the argument is checked for shell
	metacharacters, and if there are any, the entire
	argument is passed to the system's command shell
	for parsing (this is /bin/sh -c on Unix platforms,
	but varies on other platforms).  
[...]


Beispiel:

root at dx:~ # perl -e 'system("sleep 2 && echo xxx &");'
root at dx:~ # date
Fri Jan 11 13:02:07 MET 2002
root at dx:~ # datexxx

Fri Jan 11 13:02:08 MET 2002
root at dx:~ #

Ups, genau in den 2 Sekunden getippt, aber zeigt ja klar, das es
sehr wohl geht!

> Glaub ich nicht.

Aber Perl :)

> > Aber die Kommunikation mit dem subprocess wird dann schwierig...
> 
> Wieso? Kannst doch mit Signalen kommunizieren.

Hast Du schon unix Server implementiert? Signale sind nicht
einfach zu verwenden. read(2) bsp. wird abgebrochen, muß man
alles abfangen. Signale können kaum Informationen übertragen.
Signalhandler dürfen kaum Code enthalten, und sie drüfen keinen
nicht-reentranten code enthalten. signale können auch an
ungünstigen Stellen unterbrechen:

#Punkt:
my ($x,$y);

#pseudo code
signal_h()
{
	$x = 0;
	$y = 0;
}

signal(usr1, signal_h);

$x=1;
#hier triff z.B. usr1 ein
$y=1;

#hier ist x==0 und y==1, ein Punkt, der niemals so gesetzt wurde!


Das pikate hierdran ist, man kann das nichtmal mit semaphore
sperren, denn wenn der Mainthread lockt, kann der signalhandler
gar nichts tun. Also muß der signalhandler eine eigene Variable
setzen. Am besten was ganz kleines, damit das wenigstens "fast
atomar" ist. Trozdem könnte beim Auslesen oder Rücksetzen des
Flags ein dirty-read oder schlimmer auftreten! 

Man perlipc:

....
	That means that
	doing nearly anything in your handler could in theory
	trigger a memory fault and subsequent core dump.
...
	As mentioned in the signals section, because few vendors
	provide C libraries that are safely re-entrant, the
	prudent programmer will do little else within a handler
	beyond setting a numeric variable that already exists; or,
	if locked into a slow (restarting) system call, using
	die() to raise an exception and longjmp(3) out.  In fact,
	even these may in some cases cause a core dump.  It's
	probably best to avoid signals except where they are
	absolutely inevitable.

> Außerdem hast Du stdin/stdout.

Schon besser. Aber gerade stdin/stdout geht selten. Also muß man
eine PIPE machen, bzw. zwei, wenn man bi-directionale
Kommunikation benötigt. Letzeres ist schon wieder ein Dead-Lock
Kandidat, da es passieren kann, daß beide Processe gleichzeitig
ewig warten, daß der andere was schreibt. Also muß man das
synchronisieren, was wiederum aufwendig und fehlerträchtig ist.
Übrigens kriegt man auch mit stdin/stdout Probleme hin, wenn
nämlich der kernel buffer vollgeschrieben ist, und nicht abgeholt
wird, weil das Kind irgendwo blockt. Unschön. Am stdin braucht
man eh nicht für sub-process-IPC Kommunikation, macht keinen
Sinn, da ne PIPE hier immer einfacher ist (dafür sind die ja auch
da). 

In der Praxis sind das große Probleme, die richtig viel Zeit und
Arbeit kosten. Immer, wenn man was macht, muß man dies und jenes
abfangen, blocking oft vermeiden und so. Signale gehen kaum, und
wenn, hat man fast immer races. Sobald man weiter forkt, können
ja sigchlds kommen und so. 

Ich bin dabei, in der Firma ein Daemon Framework in C++ zu bauen.
Das ist inzwischen (ganz ohne IPC! Das macht Corba) sehr
aufwendig. Jeder von deamon kontrollierte Subprocess wird in
einer eigenen Session / process group gestartet, da man sonst die
"Enkel", also Kinder der subprocesse nicht loswerden kann. Der
Session-Leader process selbst läuft nochmal in einer eigenen
Session. 

Hier werden dann einfache Aufgaben wie logging kompliziert. Was
passiert, wenn zwei processe gleichzeitig in die gleiche Logdatei
schreiben? Ärger natürlich. Und so weiter.

oki,

Steffen

-- 
Dieses Schreiben wurde maschinell erstellt,
es trägt daher weder Unterschrift noch Siegel.



Mehr Informationen über die Mailingliste linux-l