Frage

Ich versuche href="http://www2.tcl.tk/8755" rel="nofollow noreferrer"> laufen tclhttpd in einem Slave-Interpreter aber leicht modifiziert, um http: // localhost: 8015 ), aber nie erreicht die Puts Linie auf die Boden, weil „der Server nicht zurück, es geht [Vwait für immer]“. Aber wenn ich versuche, „die nach 0 Trick“, z.B. Voranstellen „nach 0“ auf der Linie „$ httpd eval $ cmd“, wird der Server nicht ausgeführt, so nehme ich an „Fehler durch bgerror gehandhabt werden müssen“

Allerdings kann ich nicht gute Beispiele dafür, wie die Verwendung bgerror, und meine Forschung zeigt, dass jetzt die Konvention „Interp bgerror“ zu verwenden ist. Bitte beachten Sie die ersten paar Beispiele zurück von http://www2.tcl.tk/_ / gsearch S = bgerror ?; die erste Verbindung enthält den Wortschwall „fill in nützliche Tricks und Beispiele für die Verwendung von bgerror“, aber dann gibt es keine Proben kann ich erkennen, wie sich zu bewerben, und die zweite Verbindung kommt zu dem Schluss: „Ich bin an Beispielen, wie diese soll verwendet werden.“

package require starkit
starkit::startup

set httpd_args [list]
set httpd [interp create]
$httpd eval "set argc [llength $httpd_args]"
set cmdargv "set argv [list $httpd_args ]"
$httpd eval "set topdir $starkit::topdir"
$httpd eval $cmdargv

set cmd [list source [file join $starkit::topdir bin/httpd.tcl]]
$httpd eval $cmd

puts "if seeing this controlled has returned"
War es hilfreich?

Lösung

Das verstehe ich nicht ganz die Frage, die Sie fragen. Es klingt wie Ihr Ziel einen HTTP-Server in einem Interpreter zu starten, aber irgendwie mit dem Haupt Dolmetscher in Wechselwirkung treten. Ist das richtig? Wenn ja, was hat das mit bgerror zu tun?

Sind Sie sich bewusst, dass, obwohl Sie den Server in einem separaten Interpreter ausgeführt wird, ist es nicht in einem separaten Thread ausgeführt wird? Das heißt, man kann nicht (*) interagieren mit dem Haupt-Interpreter, während entweder Dolmetscher durch eine Vwait blockiert wird.

(*) Sie können, wenn Sie Ihre Interaktion erfolgt in Form von Tk-Widgets, die auch die Vorteile der Ereignisschleife nehmen

Was, wie bgerror zu verwenden, gibt es ein paar Möglichkeiten, wie es funktioniert. Der Standardmechanismus ruft die Funktion ‚bgerror“, die Sie definieren können zu tun, was Sie wollen. Es eine einzelne Zeichenfolge nimmt (der Text einer Fehlermeldung) und macht etwas mit ihm. Das etwas könnte es sein, drucken, den Fehler zu stdout, zeigen sie sie in einem Dialog, schreiben sie es in eine Datei, etc.

Als Beispiel betrachten wir diese interaktive Sitzung:

% proc bgerror {s} {puts "hey! I caught an error: $s"}
% # after 30 seconds, throw an error
% after 30000 {error "this is an error"}
after#0
% # after 40 seconds, terminate the event loop
% after 40000 {set ::done 1}
after#1
% # start the event loop
% vwait ::done
hey! I caught an error: this is an error
% # this prompt appears after 40 seconds or so

Sie können auch Ihre eigenen Fehler-Handler registrieren, wie in der Dokumentation für „Interp bgerror“ beschrieben. Dies kam in tcl 8,5, obwohl es eine bug das war bis 8.5.3 nicht festgelegt.

Zum Beispiel:

% set foo [interp create]
interp0
% $foo eval {proc myErrorHandler {args} {puts "myErrorHandler: $args"}}
% $foo bgerror myErrorHandler
myErrorHandler
% # after 30 seconds, throw an error
% $foo eval {after 30000 {error "this is an error"}}
after#0
% # after 40 seconds, terminate the loop
% $foo eval {after 40000 {set ::done 1}}
after#1
% $foo eval {vwait ::done}
myErrorHandler: {this is an error} {-code 1 -level 0 -errorcode NONE -errorinfo {this is an error
    while executing
"error "this is an error""
    ("after" script)} -errorline 1}
% # this prompt appears after 40 seconds or so

Hilft dies Ihre Frage beantwortet?

Andere Tipps

Komplett bearbeitet auf der Grundlage der OP Kommentare ...

Der nach 0 Trick ist die folgende Zeile ein:

after 0 $httpd eval $cmd

Was das bedeutet ist die Interp sagen Sie den Befehl in Frage ($ http eval $ cmd) auf das Ereignis Warteschlange hinzuzufügen, was bedeutet, es wird ausgeführt, sobald die Ereignisschleife gestartet (oder zurückgegeben, wenn es bereits gestartet wird). Sie können von dieser Seite in dem folgenden Kommentar die Abhängigkeit von der Ereignisschleife sehen (von Jacob Levy):

  

Ich sollte anmerken, dass dies auf der Ereignisschleife hängt aktiv.

Meine Vermutung ist, dass Sie eine Ebene tclsh, laufen, was bedeutet, Sie nie die Ereignisschleife eingeben (die Merk Shell die Ereignisschleife am Ende des Skripts eintritt, die Tcl-Shell nicht). Der Standard-Weg, um die Ereignisschleife, geben Sie den folgenden Befehl ausführen, wenn Sie bis zum Ende Ihres Tcl-Code erhalten:

# Enter the event loop and stay in it until someone 
# sets the "forever" variable to something
vwait forever

aber sagen, dass alles, was Sie nach dem Vwait wird erst ausgeführt, nachdem die Ereignisschleife verlassen wird. Wenn Sie den httpd laufen parallel zu Ihrem Code möchten, müssen Sie entweder:

  • Verwenden Sie mehrere Threads, oder schreiben Sie ... das ist wirklich nicht so schwer ist
  • Code Ereignis beruht, ..., die Sie vor einem verhungert der Ausführungszeit verstehen, auch basierte Programmierung gut genug, um zu verhindern, dass Teile des Codes erfordert.

Ich hoffe, das hilft.

Wenn ich verstanden habe richtig, was Sie tun wollen, sollten Sie den Code wie folgt aussehen, dass:

set httpd_id [thread::create -preserved]
thread::send $http_id "source [file join $starkit::topdir bin/httpd.tcl]"

Auf diese Weise haben Sie tclhttpd in einem Thread ausgeführt wird, ohne für das Vwait Problem sich Gedanken

Wenn Sie auch über jeden Fehler bei der httpd Ausführung informiert werden möchten, sendet TclHttp alle Fehler in einer Protokolldatei. Sie können den Pfad des Log konfigurieren tun:

Log_SetFile "/logs/httpd_log"

Sie müssen den httpd haben :: Paket anmelden.

Ich hoffe, das hilft.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top