2017-03-02 1 views
1

Quel est le comportement en temps haute résolution de TCL 'exec'? Je comprends qu'une commande 'fork' sera utilisée pour créer d'abord une copie de l'image mémoire du processus et ensuite continuer.Empreinte mémoire résolue en temps de TCL exec

est ici la motivation de ma question:

Un utilisateur m'a donné l'observation suivante. Une machine de 64 Go dispose d'une interface d'outil basée sur TCL avec une mémoire de 60 Go utilisée. (supposons que swap est petit). À l'invite TCL, il donne 'exec ls' et le processus se bloque avec une erreur de mémoire.

Votre avis est très apprécié. Merci, Gert

+0

Bonne question! _Tricky_ question aussi. –

Répondre

1

La commande exec appellera l'interne appel système fork(). Ceci est généralement OK, mais peut manquer de mémoire lorsque le système d'exploitation est configuré pour ne pas permuter et que le processus Tcl d'origine est très important (ou s'il y a très peu de marge, cela dépend bien sûr de la situation réelle).

Les idées que j'ai pour réduire l'utilisation de la mémoire sont soit en utilisant vfork() (par rapiéçage tclUnixPipe.c, vous pouvez définir USE_VFORK dans le makefile pour permettre que, et je ne sais pas pourquoi ce n'est pas plus largement utilisé) ou par créer un processus d'assistance au début (avant beaucoup de mémoire est utilisé) qui fera le exec s au nom de votre processus principal. Voici comment faire cette dernière option:

# 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 
} 
+0

Trouvé ce commentaire: "Avec la plupart des noyaux actuels, y compris Linux, le principal avantage de vfork a disparu à cause de la façon dont fork est implémentée. " Cela dépend donc de l'OS dans une certaine mesure. –

+0

@BradLanam Vous le penseriez, mais il s'avère que les coûts de duplication réels sont toujours un problème substantiel. Je vois cela plus avec les applications Java (où travailler avec des pipes est sérieusement ennuyeux) mais les symptômes sont assez clairs. OTOH, le problème avec vfork est que le processus parent est de nos jours beaucoup moins susceptible de s'arrêter et d'attendre en raison d'un threading beaucoup plus répandu. –

+0

Un appel à fork() échouera si le système ne s'engage pas à avoir de la mémoire disponible pour les pages copy-on-write. L'utilisation de la copie sur écriture aide à la performance, mais pas à la taille. Avec overcommit activé, Linux engagera plus de mémoire (DRAM + swap) que ne le permet réellement la sortie. Mais s'il n'y en a plus, le gestionnaire de mémoire manquera d'entrer comme un gardien de sécurité sur un vol United et de supprimer un processus en cours. –