防止tcl线程被主事件循环阻塞
问题描述:
我试图连续运行一个线程,而不是被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
仍然可以在后台运行。我怎样才能做到这一点?
答
主事件循环不会阻塞您的线程。相反,您正在使用主事件循环来在线程中执行脚本。相反,运行线程本身调度:
代码测试和工程按预期:
thread::send $::a_thread {
proc loop {} {
puts "running a thread"
after 1000 loop
}
loop
}
while 1 {
puts "loop"
after 500
}
答
答案是,当然是一个由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
谢谢,Tcl wiki的例子似乎忽略了这种情况。 – elmt 2010-11-19 14:07:49