Tcl 中的线程实际上并不像 C 线程那样工作

Thread in Tcl is not really working as C threads

在Tclsh线程包中,创建的线程不与主线程共享变量和命名空间,这与线程的C实现有很大不同。为什么在tcl线程设计中会出现这种矛盾。或者我在代码中遗漏了什么?所有的脚本语言都有类似的线程设计吗?

以下引用自 Tcl 线程文档 PDF,

thread::create . All other extensions must be loaded explicitly into each thread that needs to use them

它实际上类似于您在 C: 消息传递中使用线程的一种方式。当然,您也可以在 C 中以其他方式使用线程。但是消息传递是完全避免死锁的一种方式,因为 semaphores/mutexes 可以完全围绕消息队列进行管理,并且您在其他任何地方都不需要它们你的代码。

这实际上是Tcl 在C 级别实现的。事实上,这就是这样做的原因:避免需要信号量(以防止用户形成死锁)。

大多数其他脚本语言只是提供了一个围绕 pthreads 的薄包装器,因此如果您不小心,可能会陷入死锁。我记得早在 2000 年代初期,C 和大多数其他语言中线程编程的一般建议是实现消息传递架构以避免死锁。

由于 tcl 通常认为 API 在脚本级别公开的应该是高级别的,因此线程实现是通过内置的消息传递架构实现的。当然,还有一个方便的事实,它也避免了必须使 tcl 解释器线程安全(因此在整个解释器源代码中引入互斥量)。

使解释器线程安全并非易事。直到今天,某些语言在 运行ning 线程应用程序时会发生神秘的崩溃。有些语言花了十多年时间才消除所有线程错误。 Tcl 只是决定不尝试。 tcl 解释器足够小并且运行起来非常快,所以解决方案是简单地 运行 每个线程一个解释器。

它不是 contradiction. It's just a different model. It has its advantages and its disadvantages. The key disadvantage you already know: scripts and variables are not shared (unless you take special steps). The key advantage is that the Tcl implementation has no big global locks, and that makes it much easier to use multi-core hardware effectively and means that there are very few gotchas when doing so. Contrast this with the Python Global Interpreter Lock,这是必需的,因为 Python 使用类 C 的全局共享状态模型。

在底层,Tcl的线程是强隔离的,幕后有大量的线程共享变量,这样就可以避免锁(包括在内存管理中很多时间,否则会成为关键瓶颈) .线程间通信基于 Tcl 内置的事件队列系统;当两个线程通信时,一个线程发送一条消息并(可选)等待另一个线程响应,接收方将消息放入其内部事件队列,直到它处于准备好处理它的状态。这确实会减慢线程间通信的速度,但当它们通信时会快得多。