Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 防止tcl线程被主事件循环阻塞_Multithreading_Tcl - Fatal编程技术网

Multithreading 防止tcl线程被主事件循环阻塞

Multithreading 防止tcl线程被主事件循环阻塞,multithreading,tcl,Multithreading,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

我试图连续运行线程,而不是让它被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_循环
proc,主事件循环无限运行。我希望
a_线程
仍然可以在后台运行。如何实现这一点?

主事件循环没有阻塞线程。相反,您使用主事件循环来安排要在线程中执行的脚本。而是在线程本身中运行调度程序:

已测试代码并按预期工作:


主事件循环没有阻塞线程。相反,您使用主事件循环来安排要在线程中执行的脚本。而是在线程本身中运行调度程序:

已测试代码并按预期工作:


答案当然是斯莱贝特曼给出的。然而,调试这类事情的一种方法(特别是在更复杂的情况下)是用的结果作为每个线程打印的消息的前缀,并确保在循环的每次开始时打印消息。例如:

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
默认情况下等待脚本完成执行),并且无限循环阻止了主事件循环的启动(以及调度的重新调度)。既然你不知道是谁在做什么,那当然是混乱了

答案当然是斯莱贝特曼给出的答案。然而,调试这类事情的一种方法(特别是在更复杂的情况下)是用的结果作为每个线程打印的消息的前缀,并确保在循环的每次开始时打印消息。例如:

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
默认情况下等待脚本完成执行),并且无限循环阻止了主事件循环的启动(以及调度的重新调度)。既然你不知道是谁在做什么,那当然是混乱了

谢谢,来自Tcl wiki的示例似乎忽略了这种情况。谢谢,来自Tcl wiki的示例似乎忽略了这种情况。非常有用的提示。这是我在tcl线程方面的第一次尝试,所以这将有助于我未来的冒险。非常有用的提示。这是我在tcl线程方面的第一次尝试,因此这将有助于我未来的创业。