문제

나는 노력하고있다 슬레이브 통역사에서 tclhttpd를 실행하십시오 그러나 tclkit 내에서 실행되도록 약간 수정되었습니다. 아래 코드 아래 코드 "실행"(나는 히트 할 수 있습니다. http : // localhost : 8015) 그러나 "서버가 반환되지 않고 [vwait forever]에 들어가기 때문에 하단의 풋 라인에 도달하지 않습니다. 그러나 "Af

그러나 나는 Bgerror를 사용하는 방법에 대한 좋은 예를 찾을 수 없으며, 내 연구에 따르면 이제 컨벤션은 "Interp Bgerror"를 사용하는 것입니다. 다음으로 반환 된 첫 몇 가지 예를 참조하십시오 http://www2.tcl.tk/_/gsearch?s=bgerror; 첫 번째 링크에는 "Bgerror를 사용하기위한 유용한 트릭과 예제를 채우는"언어가 포함되어 있지만 적용하는 방법을 식별 할 수있는 샘플은 없으며 두 번째 링크는 "이것이 어떻게 사용되는지에 관심이 있습니다"라고 결론지었습니다.

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"
도움이 되었습니까?

해결책

나는 당신이 묻는 질문을 잘 이해하지 못합니다. 목표는 한 통역사에서 HTTP 서버를 시작하는 것이지만 어떻게 든 메인 통역사와 상호 작용하는 것 같습니다. 맞습니까? 그렇다면 Bgerror와 어떤 관련이 있습니까?

별도의 통역사에서 서버를 실행하고 있지만 ~ 아니다 별도의 스레드에서 실행합니까? 즉, 주 통역사와 상호 작용할 수는 없습니다.

(*) 상호 작용이 이벤트 루프를 활용하는 TK 위젯 형태를 취할 수 있습니다.

Bgerror를 사용하는 방법에 대해서는 몇 가지 방법이 있습니다. 기본 메커니즘은 원하는대로 수행하기 위해 정의 할 수있는 함수 'Bgerror'를 불렀습니다. 단일 문자열 (오류 메시지의 텍스트)이 필요하고 그와 함께 무언가를 수행합니다. 무엇 Or

예를 들어,이 대화식 세션을 고려하십시오.

% 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

"Interp Bgerror"에 대한 설명서에 설명 된대로 자신의 오류 핸들러를 등록 할 수도 있습니다. 이것은 TCL 8.5에 나왔지만 벌레 8.5.3까지 고정되지 않았습니다.

예를 들어:

% 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

이것이 귀하의 질문에 답하는 데 도움이됩니까?

다른 팁

OP의 의견에 따라 완전히 편집되었습니다 ...

After 0 트릭은 다음 줄입니다.

after 0 $httpd eval $cmd

이것이하는 일은 Interp에게 해당 명령 ($ http eval $ cmd)을 이벤트 큐에 추가하도록 지시하는 것입니다. 즉, 이벤트 루프가 시작되면 (또는 이미 시작된 경우에 반환) 실행됩니다. 해당 페이지의 다음 주석 (Jacob Levy)에서 이벤트 루프에 대한 의존도를 볼 수 있습니다.

이것은 이벤트 루프가 활성화되는 것에 달려 있습니다.

내 생각에 당신은 당신이 평범한 tclsh를 실행하고 있다는 것입니다. 즉, 이벤트 루프에 들어 가지 않음을 의미합니다 (Wish Shell은 스크립트 끝에서 이벤트 루프에 들어갑니다. TCL 쉘은 그렇지 않습니다). 이벤트 루프를 입력하는 표준 방법은 TCL 코드가 끝나면 다음 명령을 실행하는 것입니다.

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

즉, vwait 이후의 모든 것은 이벤트 루프가 종료 될 때까지 실행되지 않습니다. httpd가 코드와 병렬로 실행 되려면 다음 중 하나가 필요합니다.

  • 여러 스레드를 사용하거나 쓰기 ... 정말 어렵지 않습니다.
  • 이벤트 기반이되기위한 코드 ... 이는 코드가 실행 시간에 굶어 죽지 않도록 충분히 기반 프로그래밍을 이해해야합니다.

도움이되기를 바랍니다.

내가하고 싶은 일을 올바르게 이해한다면, 코드는 다음과 비슷해 보일 것입니다.

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

이런 식으로 vwait 문제에 대해 걱정하지 않고 Tclhttpd가 스레드에서 실행됩니다.

HTTPD 실행 중에 오류에 대해 알리려면 TCLHTTP가 모든 오류를 로그 파일로 보냅니다. 로그의 경로를 구성 할 수 있습니다.

Log_SetFile "/logs/httpd_log"

httpd :: 로그 패키지가 있어야합니다.

이게 도움이 되길 바란다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top