我如何关联两个 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()
。如果在调用 CreateInterp
和 DeleteInterp
.
期间线程 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);那里的大部分复杂性与将本质上是单向(但“可靠”)的操作转变为双向操作有关,使您可以对不同的线程进行过程调用;单向调用要简单得多。
我的代码如下所示:
myCmd::myCmd(std::string outFile) : _tclInterp(Tcl_CreateInterp()), _outFile(outFile)
{
_myParser = CC::CmdParser(_tclInterp, registerAllCommands);
}
创建 Tcl_CreateInterp()
的线程可能与 CC::CmdParser
中使用的不同。一旦所有程序完成,内部 CC::CmdParser
也会调用 Tcl_DeleteInterp()
。如果在调用 CreateInterp
和 DeleteInterp
.
如何关联或告诉同一个线程执行 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);那里的大部分复杂性与将本质上是单向(但“可靠”)的操作转变为双向操作有关,使您可以对不同的线程进行过程调用;单向调用要简单得多。