Der exec
Befehl wird den fork()
Systemaufruf intern nennen. Dies ist normalerweise in Ordnung, aber es kann sein, dass der Arbeitsspeicher erschöpft ist, wenn das Betriebssystem so konfiguriert ist, dass es nicht vertauscht wird und der ursprüngliche Tcl-Prozess sehr groß ist (oder wenn nur sehr wenig Speicherplatz zur Verfügung steht; abhängig von der tatsächlichen Situation).
Die Ideen, die ich für die Verringerung der Speichernutzung haben, sind entweder vfork()
mit (von tclUnixPipe.c
Patchen, man USE_VFORK
in der Make-Datei, das zu ermöglichen, definieren kann, und ich weiß nicht, warum das nicht mehr weit verbreitet ist) oder durch Erstellen eines Hilfsprozesses früh (vor viel Speicher verwendet wird), die die exec
s im Namen Ihres Hauptprozesses tun wird. Hier ist, wie die letztere Option zu tun:
# This is setup done at the start
set forkerProcess [open "|tclsh" r+]
fconfigure $forkerProcess -buffering line -blocking 0
puts $forkerProcess {
fconfigure stdout -buffering none
set tcl_prompt1 ""
set tcl_prompt2 ""
set tcl_interactive 0
proc exechelper args {
catch {exec {*}$args} value options
puts [list [list $value $options]]
}
}
# TRICKY BIT: Yield and drain anything unwanted
after 25
read $forkerProcess
# Call this, just like exec, to run programs without memory hazards
proc do-exec args {
global forkerProcess
fconfigure $forkerProcess -blocking 1
puts $forkerProcess [list exechelper {*}$args]
set result [gets $forkerProcess]
fconfigure $forkerProcess -blocking 0
while {![info complete $result]} {
append result \n [read $forkerProcess]
}
lassign [lindex $result 0] value options
return -options $options $value
}
Gute Frage! _Tricky_ Frage auch. –