我有一个使用 tkinter 编写的界面。在该界面内,我有一个 matplotlib 图。在后台,我让 zmq 连接到服务器以获取数据。我正在使用 python 的多处理模块,其中有一个队列共享数据和一个为所有 zmq 通信运行的进程。
在 GUI 中,我可以设置一个按钮来使用以下函数更新绘图:
def addData(self):
if not self.data.empty():
print "Have Data!"
self.hist.addQueue(self.data)
self.hist.updatePlot()
else:
print "No Data"
但是,如果我尝试创建另一个基本上将其放入 while True 中的进程,我会收到以下错误:
X Error of failed request: RenderBadPicture (invalid Picture parameter)
Major opcode of failed request: 139 (RENDER)
Minor opcode of failed request: 7 (RenderFreePicture)
Picture id in failed request: 0x160000a
Serial number of failed request: 2686
Current serial number in output stream: 2690
[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
python: ../../src/xcb_io.c:274: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.
fish: Job 1, “python clientGUI.py ” terminated by signal SIGABRT (Abort)
我找不到关于此错误的任何信息,似乎与我正在做的任何事情有关。
如果需要,我可以提供我的代码的其他部分,但有很多代码我不想用它来淹没这个问题。
请您参考如下方法:
Excuse me for not following your post-mortem trails
第 0 步:(重新)调整组件的概念
座右铭:虽然调试错误导向的架构是可能的,但与更好、更直接的设计相比,由此产生的效率相当低
Component Inventory:
Tkinter 是一个非常智能的框架,围绕 .mainloop() (中央调度程序)工作,并允许软实时调度其他任务/包括。消息代理池的计划/预定查询。
Queue 是一种中介服务,它在一个端点上接收任何消息并将(所有 此类消息)传送到相对端点。由于所有消息到接收点的非托管无上下文传递,基于队列的自动化对于具有软调度的分布式系统中的 GUI 刷新功能代理是不可行的。 (引用下面关于全状态 GraphModelAGENT 的评论,它更适合与 Tkinter.mainloop()
Process 允许运行单独的子进程并分配角色,不仅通过 Tkinter 任务(通过时间触发的 .mainloop() 和/或事件触发的回调在预定的时间段中调用)还要运行一个完全独立的 <<_aStateFullGraphAGENT_>> ,它有两个职责:
[a] 与 Tkinter 通信以与 Tkinter 的 SIGRTU_aRequestToUpdate
+
[b] 与“服务器”通信以更新 AGENT 的内部 GUI-ModelPART(无需向任何第三方推送,通过 FIFO-Queue(过载)加载 GUI-VisualPART 的次数越少(GUI-VisualPART 不必处理和重新绘制 GUI 模型的所有“过去”状态,而是成为一个轻量级的 Repaint-On-Demand 进程,只处理最近的状态图(已经组装并连续(来自 Tkinter 的异步...)在 aStateFullGraphAGENT 中维护)
第 1 步:解决方法
-- avoid
FIFO-Queuethat has to deliver all "GUI-states", that 've become obsolete++ add
aStateFullGraphAGENTto maintain the "recent" GUI-state++ use
ZeroMQintelligent process-to-process messaging layer without any inter-thread blocking
ZeroMQ 相关的消息传递开销是微秒级的,这不会对任何 Repaint-On-DemandGUI 相关操作产生不利影响,因此安排 Tkinter 刷新率有很大的自由度,是它是 .mainloop() - 计划的或事件驱动的。
引用:>>> https://stackoverflow.com/a/25769600/3666197
第 2 步:验证/调整 GUI 重绘延迟/开销的可行性
引用:项目 2 中的处理时间 >>> https://stackoverflow.com/a/25530099/3666197
