python - 使用 matplotlib 运行线程会导致 python 崩溃

标签 python multithreading matplotlib tkinter

我有一个程序有 2 个非常简单的线程:

  • 串口监听一个
  • 一个用于文本 UI

我还有一个 matplotlib animation 在我的 main() 中运行。它有一个 scope 类,这是来自 matplotlib 的示例.

当程序开始运行时,它显示了情节,一切正常。问题是,只要用户输入一个键,程序就会崩溃,python 会以 fatal error 退出。

ui 线程与matplotlibscope 类无关。如果我删除创建图的代码,ui 线程没有问题,程序运行顺利。我还注意到我系统上的 matplotlib 使用 tkinter 来创建窗口。

对于为什么 matplotlib animation 会导致问题,您有任何提示或经验吗?线程不能与 matplotlib plot 一起使用吗?

我在 Windows7 的命令行窗口中使用 Python 2.7 运行它。

matplotlib 版本:2.0.2 Tkinter 版本:8.5

错误:

Fatal Python error: GC object already tracked

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

或者这个错误:

TclStackFree: incorrect freePtr. Call out of sequence?

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

代码:

    import threading
import serial
from matplotlib.lines import Line2D
import matplotlib.pyplot as plt
import matplotlib.animation as animation

class listner(threading.Thread):

        def __init__(self,port):
            threading.Thread.__init__(self)
            self.sport=None
            self.is_running=True
            self.init_port(port)

        def run(self):
            print ' Reading from Port'
            while self.is_running:
                try:
                    self.sport.read(1)
                except:
                    print 'Error reading port'

        def init_port(self,port):
            print '1'
            if self.sport==None or not self.sport.is_open :
                try:

                    self.sport = serial.Serial(port,115200)
                    self.sport.timeout = 1
                    self.sport.reset_input_buffer()
                    self.sport.reset_output_buffer()
                    self.port_open=True
                except:
                    print "    Port error Listener Initing\n",self.port_open,'\n',self.sport
            else:
                pass

        def process(self):
            pass


class ui(threading.Thread):

        def __init__(self):
            threading.Thread.__init__(self)     
            self.running = True

        def run(self):

            print 'Starting UI:\n'
            while self.running:
                print ' Enter input ''S'':\n'
                user = raw_input()



def main(port):

        listner_thread = None
        try:
            listner_thread = listner(port)
            listner_thread.start();
        except:
            print "Listener Thread Failed To Start"
            return

        ui_thread=None
        try:
            ui_thread = ui()
            ui_thread.start()          
        except:
            print "UI Thread Failed To Start"
            return

        run_charts()



def run_charts():
        fig, (ax1, ax2) = plt.subplots(2, 1)

        scope1 = Scope(ax1)
        ani1 = animation.FuncAnimation(fig, scope1.update, emit_ch1, interval=10,blit=True)

        scope2 = Scope(ax2)
        ani2 = animation.FuncAnimation(fig, scope2.update, emit_ch2, interval=10,blit=True)

        plt.show()

def emit_ch1():
    yield 0.001

def emit_ch2():
    yield -0.001

class Scope(object):
        def __init__(self, ax, maxt=2, dt=0.02):
            self.ax = ax
            self.dt = dt
            self.maxt = maxt
            self.tdata = [0]
            self.ydata = [0]
            self.line = Line2D(self.tdata, self.ydata)
            self.ax.add_line(self.line)
            self.ax.set_ylim(-.009, 0.009)
            self.ax.set_xlim(0, self.maxt)

        def update(self, y):
            t = self.tdata[-1] + self.dt
            self.tdata.append(t)
            self.ydata.append(y)
            self.line.set_data(self.tdata, self.ydata)
            return self.line,



if __name__ == '__main__':
        main('COM11')

最佳答案

第一个错误“致命 Python 错误:已跟踪 GC 对象”已于 2013 年关闭,状态为“CLOSED WONTFIX”参见 bug report在 Bugzilla 上

它似乎在 2015 年再次提出 [与 dask 相关] 时的临时修复是 use a single thread使用此代码:

   import dask
   dask.set_options(get=dask.async.get_sync)

但问题实际上在于 dataframe.read_csv 问题。

问题是 eventually solved在更高版本的 Pandas 中。如果您升级您的 matplotlib 版本,该问题很可能也会通过类似的修复得到解决。

希望对你有帮助

关于python - 使用 matplotlib 运行线程会导致 python 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44555787/

相关文章:

java - java中无法同时读取两个文件

java - 媒体播放器 prepare() 方法上的 IllegalStateException

python - 如何消除具有共享轴的子图上的额外空白?

python - 如何设置颜色条的科学记数限制?

用于抛硬币问题的 Python 代码

python - Celery 不排队到远程代理,而是将任务添加到本地主机

python - 如何从长表中有效地创建 SparseDataFrame?

android - 为什么AsyncTask的doInBackground()中不能使用Context

python - bool 掩码 Groupby Any 并创建指标

python - 向 Seaborn 点图添加图例