2010-11-19 88 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