我如何关联两个 Tcl_Interp?

How do I associate two Tcl_Interp?

我的代码如下所示:

myCmd::myCmd(std::string outFile) : _tclInterp(Tcl_CreateInterp()), _outFile(outFile) 
{
   _myParser = CC::CmdParser(_tclInterp, registerAllCommands);
}

创建 Tcl_CreateInterp() 的线程可能与 CC::CmdParser 中使用的不同。一旦所有程序完成,内部 CC::CmdParser 也会调用 Tcl_DeleteInterp()。如果在调用 CreateInterpDeleteInterp.

期间线程 ID 不同,将会出现问题

如何关联或告诉同一个线程执行 Tcl_CreateInterp()(在构造函数中)和 Tcl_DeleteInterp()(在 CmdParser 中)。

请注意,CC::CmdParser 是第三方 API,我没有源代码。

Tcl 解释器对象在内部广泛使用特定于线程的数据以避免大多数全局锁。这甚至包括线程特定的内存管理池,至少对于公共分配,Tcl 代码作为初始化解释器状态的一部分执行,所以 真的 不可能使用解释器在与创建它的线程不同的线程中。 Tcl 库 检查 你在几个地方是否正确使用它,至少在某些构建模式下,并将使过程 abort() (或 Windows相当于)如果你不遵守规则;这比由于不尊重基本假设而导致的崩溃要友好得多……

这意味着您必须在同一线程上创建、使用和销毁解释器。

如果您不能保证包含对象在创建它的同一个线程中使用,可能会建议您延迟初始化 Tcl 解释器。您可能认为这会导致处理不是'这并不是真正的 C++ 方式,但是解释器的线程绑定特性意味着您真的没有其他选择。 (您可能想查看 Tcl_CreateExitHandler() 以获取有关在线程消失时清理解释器的帮助,但这仅在调用 Tcl_FinalizeThread()Tcl_ExitThread() 时有帮助;如果您正在在 C++ 方面线程混杂,那么你很有可能会遇到各种各样的问题。)

如果 C++ 部分坚持使用多线程,您将不得不为 Tcl 代码使用一个线程,并使用线程间消息传递让其他线程告诉它一些事情。 Tcl_ThreadQueueEvent(). The canonical way to use that is the thread package, and that includes the canonical example of how to do so (github.com/tcltk/thread/generic/threadCmd.c);那里的大部分复杂性与将本质上是单向(但“可靠”)的操作转变为双向操作有关,使您可以对不同的线程进行过程调用;单向调用要简单得多。