Tkinter崩溃(恐慌)调用Tcl_AppendFormatToObj

时间:2014-11-20 07:13:30

标签: tkinter tcl panic

我编写了一个使用Tkinter作为GUI的Python应用程序。它有第二个用于TCP / IP通信的线程(实际上是XMLRPC,允许labview连接并进行一些调用)。两个线程与一对线程安全队列通信。运行了几天之后,就崩溃了。我没有得到完整的追溯。到目前为止,我得到的最好的是“Tcl_AppendFormatToObj called with shared object”显然,这来自以下Tcl函数:

Tcl_AppendFormatToObj(..)
{
...
    if (Tcl_IsShared(appendObj)) {
    Tcl_Panic("%s called with shared object", "Tcl_AppendFormatToObj");
    }

如果导致问题,请格式化字符串。有什么建议?我现在正在winpdb下的Windows 7上运行脚本并等待并希望在“恐慌”再次发生时有用的跟踪。

2 个答案:

答案 0 :(得分:3)

事实证明,其中一个队列不是线程安全的。 Tk偶数队列不是线程安全的。因此,使用tk的root.after()将某些内容放在tk的偶数队列中,从另一个线程中引发间歇性问题。相反,创建一个真实的队列,并使非tk循环线程填充到队列中,并使tk线程中的代码监视队列的另一侧。所以在tk循环中,编写一个清空真实队列的函数(并根据它找到的内容做一些事情)。使用after()使该函数调用自身。

答案 1 :(得分:1)

Tcl的Tcl_Obj值系统的语义 - 具有值身份,与Python不同 - 要求值可观察常量。在实践中,这意味着在存在单个引用(例如,来自Tcl变量)的情况下,可以修改该值,但是在存在多个引用(两个变量,变量和参数等)的情况下,该值可能不是改变了(除了让它的类型发生变异,一个在Tcl中称为“闪烁”的过程,因为类型并不意味着在Tcl中是可观察的值的方面),以防止“怪异的 - 远距离“突变。这些规则由值变异函数强制执行,其中Tcl_AppendFormatToObj是一个。

为什么有多个对正在变异的值的引用不太清楚。我根据你的说法猜测你在一个正在改变该值的线程和另一个使用该值的线程之间进行了竞争(在此期间它暂时获得了第二个引用)。种族条件丑陋以追捕所有语言。在低级别,修复通常是使用Tcl_DuplicateObj在变异线程中获取非共享副本,然后可以在更改后写入共享存储,但我怀疑这会破坏事物在您的线程代码中的其他地方,您可能在读者方面假设引用没有改变。

将其排序将是棘手的。修复此问题的Tcl方法是停止尝试跨线程共享值,而是切换到消息传递,其中“writer”线程实际上向“reader”线程发送消息以更新其状态。 (如果有必要,这可以扩展到拥有多个读者,因此它不是全部坏,并且可以在没有全局锁定状态的情况下完成,这甚至更好.Tcl不需要像Python这样的任何东西。全局解释器锁,因为它首先通过线程更强烈地对所有内容进行分区。)我不知道如何将其转换为可以在Python中实现的内容...