我正在尝试连续运行一个线程,而不是让它被tcl主事件循环阻塞。 这是我正在尝试做的一个简单示例:
#!/bin/sh
#\
exec tclsh "$0" "$@"
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
仍然可以在后台运行,我希望如此。我怎样才能做到这一点?
答案 0 :(得分:6)
主事件循环没有阻塞你的线程。相反,您使用主事件循环来指示要在线程中执行的脚本。相反,在线程本身中运行调度程序:
代码经过测试并按预期工作:
thread::send $::a_thread {
proc loop {} {
puts "running a thread"
after 1000 loop
}
loop
}
while 1 {
puts "loop"
after 500
}
答案 1 :(得分: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
等待脚本默认完成执行),并且无限循环阻止了启动主事件循环(因此重新安排调度)。既然你不知道谁在做什么,当然有混乱!