防止 tcl 线程被主事件循环阻塞
我试图连续运行一个线程,而不让它被 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 过程,并且主事件循环无限运行。如果 a_thread
仍然可以在后台运行,我希望它。我怎样才能实现这个目标?
I am trying to run a thread continuously and not have it become blocked by the tcl main event loop.
Here is a simple example of what I'm trying to do:
#!/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
In this code, the infinite_loop
proc is called and the main event loop runs infinitely. I would like it if the a_thread
could still run in the background though. How can I achieve this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
主事件循环不会阻塞您的线程。相反,您使用主事件循环来安排要在线程中执行的脚本。相反,在线程本身中运行调度程序:
代码经过测试并按预期工作:
The main event loop is not blocking your thread. Instead you are using the main event loop to shedule scripts to be executed in the thread. Instead, run the scheduler in the thread itself:
Code tested and works as expected:
答案当然是slebetman给出的。但是,调试此类事情(尤其是在更复杂的情况下)的一种方法是在每个线程打印的消息前添加
thread::id
,并确保在每次循环的开始处打印一条消息。例如:这会告诉您调度只发生一次,另一个线程中的运行是同步发生的(
thread::send
默认情况下等待脚本完成执行),并且无限循环阻止主事件循环的启动(从而阻止重新调度调度)。既然你不知道谁在做什么,当然会很混乱!The answer is, of course, the one given by slebetman. However, one way to debug this sort of thing (especially in more complex cases) is to prefix the messages printed by each thread by the result of
thread::id
, and to make sure you print a message at the start of each time round the loop. For example:That would have told you that the dispatch was happening once, that the running in the other thread is happening synchronously (
thread::send
waits for the script to finish executing by default), and that the infinite loop is preventing the startup of the main event loop (and hence the rescheduling of the dispatch). Since you didn't know who was doing what, of course there was confusion!