使用wxPython进行多处理没有响应
我使用wxPython作为数据采集系统的前端,后端使用PyDAQmx与国家仪器卡接口 当调用循环来收集数据时,显然gui会阻塞,因此我使用threading.thread将采集模块放在一个单独的线程中。然而,数据来得如此之快,以至于我们实际上需要不止一个内核,我相信线程是不能做到的 接下来,我尝试使用multiprocessing.process&Queue生成一个单独的进程来报告数据,非常简单使用wxPython进行多处理没有响应,python,user-interface,wxpython,multiprocessing,Python,User Interface,Wxpython,Multiprocessing,我使用wxPython作为数据采集系统的前端,后端使用PyDAQmx与国家仪器卡接口 当调用循环来收集数据时,显然gui会阻塞,因此我使用threading.thread将采集模块放在一个单独的线程中。然而,数据来得如此之快,以至于我们实际上需要不止一个内核,我相信线程是不能做到的 接下来,我尝试使用multiprocessing.process&Queue生成一个单独的进程来报告数据,非常简单 captureProcess = Process(target=acquire, args=(sel
captureProcess = Process(target=acquire, args=(self.settings, self.queue,))
captureProcess.start()
数据通过以下方式沿队列发送:
queue.put( (i, j, c, aiData.value) )
然后又拿起了
(scan, interval, count, ai) = queue.get()
现在奇怪的是gui没有阻塞,因为我可以更新主wx.Frame上的一些pyplot图,但是与它的任何交互(单击菜单等)都会立即导致程序无响应和崩溃。有人知道为什么会这样,或者有什么解决办法吗
非常感谢你的帮助。我正在Windows 7上使用anaconda。确保线程中没有GUI交互,也没有GUI中的直接线程交互。GUI可以调用线程中的setter函数来更改线程定期检查的成员值,并且线程可以通过发布事件和附加数据来产生GUI结果
wxPython的一个可爱特性是定制事件可以为您携带任何类型的数据
队列的一个特点是,如果插槽已满,它将挂起,当GUI执行菜单单击等操作时,您将不会为队列提供服务,我怀疑您已溢出-您应该捕获完整异常并执行一些操作,例如丢弃数据并设置数据丢失标志。Make绝对确保线程中没有GUI交互,GUI中也没有直接的线程交互。GUI可以调用线程中的setter函数来更改线程定期检查的成员值,并且线程可以通过发布事件和附加数据来产生GUI结果
wxPython的一个可爱特性是定制事件可以为您携带任何类型的数据
队列的一个特点是,如果插槽已满,它将挂起,当GUI执行菜单单击等操作时,您将无法为队列提供服务,我怀疑您已溢出-您应该捕获完整异常,并执行一些操作,例如丢弃数据和设置数据丢失标志。尝试启动该过程早期-在设置wxpython之前。向数据收集过程中推送的状态越少越好。您是否尝试将wx.Yield()合并到循环中?这将允许GUI更新,然后返回循环。你可能不需要用这个把它穿出来,但我也没有用过蟒蛇,所以我不知道它能做什么。谢谢你的帮助。我无法提前启动该流程,因为它需要在用户开始数据捕获时启动。由于循环处于单独的进程中,因此对于wx.Yield(),我需要传递当前应用程序的副本,但无法对其进行pickle处理,因此它似乎无法工作。欢迎您提供更多建议。请尝试在设置wxpython之前尽早启动此过程。向数据收集过程中推送的状态越少越好。您是否尝试将wx.Yield()合并到循环中?这将允许GUI更新,然后返回循环。你可能不需要用这个把它穿出来,但我也没有用过蟒蛇,所以我不知道它能做什么。谢谢你的帮助。我无法提前启动该流程,因为它需要在用户开始数据捕获时启动。由于循环处于单独的进程中,因此对于wx.Yield(),我需要传递当前应用程序的副本,但无法对其进行pickle处理,因此它似乎无法工作。谢谢你的回答,谢谢你的建议。线程与外部对象的唯一通信是通过queue.put(…)调用。因为我不认为这些是指针,所以采集模块中的每一位数据都应该与gui中的任何内容分开。在两个模块之间传递的唯一其他数据位在设置模块中,但我相信这些数据是经过pickle和unpickle处理的(因此是复制的,而不是指针),在捕获过程中它们肯定不会被修改。请参阅expanded answer@kezz_smc。谢谢!你的回答让我意识到我是个白痴,采集模块是线程化的,但从中接收数据的模块不是,这意味着它阻塞了gui。现在所有问题都解决了。干杯@kezz_smc-打勾和/或加上一点就好了!(对于加号1,没有足够的代表-抱歉)谢谢您的回答。线程与外部对象的唯一通信是通过queue.put(…)调用。因为我不认为这些是指针,所以采集模块中的每一位数据都应该与gui中的任何内容分开。在两个模块之间传递的唯一其他数据位在设置模块中,但我相信这些数据是经过pickle和unpickle处理的(因此是复制的,而不是指针),在捕获过程中它们肯定不会被修改。请参阅expanded answer@kezz_smc。谢谢!你的回答让我意识到我是个白痴,采集模块是线程化的,但从中接收数据的模块不是,这意味着它阻塞了gui。现在所有问题都解决了。干杯@kezz_smc-打勾和/或加上一点就好了!(没有足够的代表参加加号1-抱歉)