2010-11-19 85 views
1

我試圖連續運行一個線程,而不是被tcl主事件循環阻塞。 這裏是什麼,我試圖做一個簡單的例子:防止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 

在這段代碼中,infinite_loop PROC被稱爲與主事件循環無限運行。我想如果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 wiki的例子似乎忽略了這種情況。 – elmt 2010-11-19 14:07:49

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 2010-11-19 14:09:55