2010-11-19 4 views
1

스레드를 지속적으로 실행하려고하는데 tcl 메인 이벤트 루프에 의해 차단되지 않도록하십시오. infinite_loop 시저를 호출하고 메인 이벤트 루프는 무한히 실행됩니다,이 코드에서tcl 스레드가 메인 이벤트 루프에 의해 차단되는 것을 막으십시오.

#!/bin/sh 
#\ 
exec tclsh "$0" "[email protected]" 

package require Thread 

set ::a_thread [thread::create {thread::wait}] 

proc start_a {} { 
    thread::send $::a_thread { 
    puts "Running a thread" 
    } 
    after 1000 a_start 
} 

proc infinite_loop {} { 
    while {1} { 
    puts "Loop" 
    after 500 
    } 
} 

start_a 
infinite_loop 

vwait forever 

: 는 여기에 내가 할 노력하고있어 간단한 예입니다. a_thread가 여전히 백그라운드에서 실행될 수 있다면 좋겠다. 이것을 어떻게 할 수 있습니까?

답변

6

메인 이벤트 루프가 스레드를 차단하지 않습니다. 대신 메인 이벤트 루프를 사용하여 스레드에서 실행될 스크립트를 스케줄링합니다. 예상대로 코드가 테스트 및 작동

: 대신 스레드 자체 스케줄러를 실행

thread::send $::a_thread { 
    proc loop {} { 
     puts "running a thread" 
     after 1000 loop 
    } 
    loop 
} 

while 1 { 
    puts "loop" 
    after 500 
} 
+0

감사합니다. Tcl 위키의 예제는 이러한 유형의 상황을 간과 한 것 같습니다. – elmt

5
물론

대답은, slebetman에 의해 주어진 하나. 그러나 이런 종류의 디버깅 방법 (특히 복잡한 경우)은 각 스레드가 인쇄 한 메시지 앞에 thread::id을 접두어로 붙이면 시작시마다에 메시지를 인쇄합니다. 루프 라운드. 예를 들면 :

package require Thread 

set ::a_thread [thread::create {thread::wait}] 

proc start_a {} { 
    puts "[thread::id]: Dispatch to $::a_thread" 
    thread::send $::a_thread { 
    puts "[thread::id]: Running a thread" 
    } 
    after 1000 a_start 
} 

proc infinite_loop {} { 
    while {1} { 
    puts "[thread::id]: Loop" 
    after 500 
    } 
} 

start_a 
infinite_loop 
puts "[thread::id]: Start main event loop" 
vwait forever 

파견이 다른 스레드의 실행은 (기본적으로 실행이 완료 될 때까지 스크립트 thread::send 대기) 기적이 일어나고 있는지, 한 번 일어나고, 그리고 한 사실을 말했을 것이라는 무한 루프가 메인 이벤트 루프의 시작을 방해합니다 (따라서 디스패치 일정 조정). 당신이 누가 무엇을하고 있는지 알지 못했기 때문에 당연히 혼란이있었습니다!

+0

매우 유용한 팁. 이것은 tcl 스레딩에서의 첫 번째 찌르기입니다. 그래서 이것이 나의 미래 벤처에 도움이 될 것입니다. – elmt

관련 문제