我在使用Tcl_DeleteInterp()API时遇到了一些问题(在solaris上)。我在我的应用程序中使用了这个Tcl_DeleteInterp()来删除解释器。我发现奇怪的是使用这个API的过程大约持续20分钟。我用truss命令附加了进程,发现该进程持续执行以下函数将近20分钟。
15.6541 0.0002 -> libtcl8.4:Tcl_DeleteInterp(0x41748, 0x0, 0x0, 0x0)
15.6580 0.0039 -> libc:free(0x288f8, 0x0, 0x0, 0x0)
15.6583 0.0003 -> libc:mutex_unlock(0xff0424e8, 0x0, 0x0, 0x0)
15.6584 0.0001 <- libc:free() = 0
15.6588 0.0004 -> libc:free(0x474b0, 0x0, 0x0, 0x0)*
...
...
有人可以帮我解释为什么函数Tcl_DeleteInterp调用这些函数? 我还检查了为Tcl_DeleteInterp()完成的实现,但没有找到任何线索。
由于
答案 0 :(得分:0)
Tcl_DeleteInterp
删除Tcl解释器上下文。作为其中的一部分,它会破坏该解释器中的命名空间,命令和变量(Tcl没有 true 全局变量;一切都始终是特定解释器上下文的本地化)。该删除反过来会将内存释放回主内存管理器和可能的操作系统;这就是调用free()
的原因;它可能在某些配置中间接调用,但会被调用。 (如果在解释器上下文中存在活动执行 - 即调用Tcl_Eval()
或其相关函数之一 - 某些删除将被推迟,直到执行完成。)还有一些回调(嗯,其中很多都可以设置为检测各种删除;那些可以(也很可能会)释放的东西。
我不知道导致挂起的原因是什么,但是猜测看起来你有另一个线程正在敲击系统内存分配器,保持内存分配器的全局锁定相当紧张。如果是这样的话,那就太糟糕了。在这种情况下,您可能最好尝试升级到支持线程的Tcl 8.5或8.6版本(我建议无论如何; 8.4现在不支持非商业支持),因为它使用的是自定义内存分配器。 t几乎经常从全局内存池中分配(和解除分配)。我不知道这会解决问题;我怀疑这个bug不是在Tcl的实现中,而是在其他代码中。 (它肯定不在Tcl脚本中,除非你有一些花哨的扩展代码导致问题。)