我目前正在研究一种代码,该代码将通过串行通信连续绘制数据,同时还允许用户输入(以raw_input的形式)来控制作业,例如启动/停止/清除绘图和设置保存数据的文件名。目前,我尝试通过额外的线程来读取用户输入并将其转发到程序,同时连续绘制并保存数据。
不幸的是,我遇到了一些错误,其中在绘图循环期间输入的命令将程序冻结2分钟左右,我认为这与matplotlib不是线程安全有关,其中在循环时输入命令不使用绘图库将在1-2秒内产生响应。
我试图从线程切换到多处理库以试图缓解问题无济于事,程序不会显示情节,导致我相信绘图过程永远不会开始(绘图命令是第一个命令它)。如有必要,我可以发布任何一个程序的代码或相关部分。
我想知道是否有任何解决这些问题的方法,或者我是否应该重新考虑如何编程。关于结合用户意见的不同方式的任何建议也是受欢迎的。
由于
答案 0 :(得分:0)
如果matplotlib不是线程安全的,那么正确的做法是通过单个事件queue将所有输入序列化到matplotlib中。 Matplotlib可以从队列中检索项目,直到队列为空,然后处理所有新参数。
您的串行通信代码和raw_input应该只是将数据放在此队列中,而不是尝试与matplotlib直接通信。
你的matplotlib线程将做以下三件事之一:(1)等待新数据; (2)检索新数据并对其进行处理(例如,将其附加到要绘制的数组或更改输出文件名)并且只要队列不为空就保持这种状态,或者如果是,则保持状态(3) ;或(3)调用matplotlib进行绘图,然后循环回状态(1)。
如果要从raw_input实现多个操作命令,则可以添加一些辅助状态变量。例如,如果从队列中读取'stop',那么您将设置一个变量,该变量将导致状态(3)跳过绘图并直接进入状态(1),如果从队列中读取'start',你会重置这个变量,并在收到数据时重新开始绘图。
你可能会认为你想要做一些奇特的事情:“如果我看到数据,请等到确保在我开始策划之前没有更多的数据。”这通常是个错误。你必须非常小心地调整你的等待时间,然后由于输入数据的时间安排,你仍然会发现你的绘图从未发生过的时间。如果您已收到数据(您处于状态2),并且队列为空,则只需绘制!在这样做的时间内,如果有4个数据点进入,那么下次你将再绘制4个......