Python 当列表长度增加时,动画打印挂起

Python 当列表长度增加时,动画打印挂起,python,matplotlib,wxpython,python-multiprocessing,Python,Matplotlib,Wxpython,Python Multiprocessing,对于我的大学项目,我正在用python开发一个流量生成脚本。此流量生成脚本利用多处理模块以并发方式生成大量http流量。我的脚本运行良好,现在我正在尝试使用wxpython构建一个用户友好的GUI来操作这些脚本。我将这两个脚本分开。在我的GUI脚本中,我导入了我的流量生成(work)脚本,然后调用它的函数(work.time\u func()或work.requests\u func())在GUI上由用户启动时运行多进程。到目前为止,我的剧本还不错。此外,在我的wxpython面板中,我添加了一

对于我的大学项目,我正在用python开发一个流量生成脚本。此流量生成脚本利用多处理模块以并发方式生成大量http流量。我的脚本运行良好,现在我正在尝试使用wxpython构建一个用户友好的GUI来操作这些脚本。我将这两个脚本分开。在我的GUI脚本中,我导入了我的流量生成(work)脚本,然后调用它的函数(work.time\u func()或work.requests\u func())在GUI上由用户启动时运行多进程。到目前为止,我的剧本还不错。此外,在我的wxpython面板中,我添加了一个图表,该图表绘制了与流量生成脚本(work.rt(multiprocessing.Manager().list())-->相关的一些数据(各个进程之间的共享列表),该脚本实际上是所有进程之间的共享数据)。现在要在这里绘制的数据长度(len(work.rt))达到1,00,00000,但是我的GUI在仅绘制了大约2500个数据后就挂起了。这里有什么问题?如何克服它?我使用的是centos 6.5。这是我的密码:

import work #traffic generation script
import wx.lib.scrolledpanel as scrolled
import matplotlib.animation as anim
import matplotlib.figure as mfigure
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg as NavigationToolbar
import time
import wx
import os
import paramiko
import sys
from paramiko import SSHConfig
from paramiko import SSHClient
from multiprocessing import Value
import thread
class TabPanel1(scrolled.ScrolledPanel):
    def __init__(self,parent):
        scrolled.ScrolledPanel.__init__(self,parent=parent)
        self.SetDoubleBuffered(True)
        self.label_0=wx.StaticText(self,-1,"Mode of Operation:",(40,25))
        self.label_0_list=['Request Based','Time Based']
        self.label_0_combo=wx.ComboBox(self,-1,'None',(200,25),wx.DefaultSize,self.label_0_list,wx.CB_DROPDOWN)
        self.label_1=wx.StaticText(self,-1,"Number of Clients:",(40,75))
        self.label_1_list=['1','2','3','4','5','10','15','20','25','30','35','40','45','50']
        self.label_1_combo=wx.ComboBox(self,-1,'None',(200,75),wx.DefaultSize,self.label_1_list,wx.CB_DROPDOWN)
        self.label_2=wx.StaticText(self,-1,"Actions:",(40,125))
        self.label_2_list=['Web','Download','Video']
        self.label_2_combo=wx.ComboBox(self,-1,'None',(200,125),wx.DefaultSize,self.label_2_list,wx.CB_DROPDOWN)
        self.label_3=wx.StaticText(self,-1,"Number of Servers:",(40,175))
        self.label_3_list=['1','2','3','4','5','6','7','8','9','10']
        self.label_3_combo=wx.ComboBox(self,-1,'None',(200,175),wx.DefaultSize,self.label_3_list,wx.CB_DROPDOWN)
        self.label_4=wx.StaticText(self,-1,"Size of File:",(40,225))
        self.label_4_list=['small-files','0to1kb','10kb','20kb','50kb','70kb','100kb','200kb','500kb','700kb','1mb','2mb','video1.2mb','video2.2mb','video2mb','video3mb','allfiles']
        self.label_4_combo=wx.ComboBox(self,-1,'None',(200,225),wx.DefaultSize,self.label_4_list,wx.CB_DROPDOWN)
        self.label_5=wx.StaticText(self,-1,"RampUpTime(ms):",(40,275))
        self.label_5_list=['500','750','1000','2000','5000']
        self.label_5_combo=wx.ComboBox(self,-1,'None',(200,275),wx.DefaultSize,self.label_5_list,wx.CB_DROPDOWN)
        self.label_6_list=['1minute','5minutes','10minutes','15minutes','30minutes','1hour','2hours','3hours','4hours','5hours','6hours','10hours','12hours','15hours','18hours','24hours','Mode is Request Based']
        self.label_6=wx.StaticText(self,-1,"Test Time:",(40,325))
        self.label_6_combo=wx.ComboBox(self,-1,'None',(200,325),wx.DefaultSize,self.label_6_list,wx.CB_DROPDOWN)
        self.label_7_list=['10000','20000','40000','50000','70000','100000','200000','500000','700000','1000000','Mode is Time Based']
        self.label_7=wx.StaticText(self,-1,"Number of Requests:",(40,375))
        self.label_7_combo=wx.ComboBox(self,-1,'None',(200,375),wx.DefaultSize,self.label_7_list,wx.CB_DROPDOWN)
        self.failed=wx.StaticText(self,-1,"Failed Requests:",(400,25))
        self.result=wx.StaticText(self, label="",pos=(525,25))  
        self.result.SetForegroundColour(wx.RED)
        self.scripttime=wx.StaticText(self,-1,"Script_Run_Time:",(400,50))
        self.tresult=wx.StaticText(self, label="",pos=(525,75)) 
        self.tresult.SetForegroundColour(wx.RED)    
        self.ok=wx.Button(self,label="OK",pos=(40,425))
        self.ok.Bind(wx.EVT_BUTTON,self.onok)
        self.cancle=wx.Button(self,label='Cancle',pos=(140,425))
        self.cancle.Bind(wx.EVT_BUTTON,self.oncancle)
        self.run=wx.Button(self,label="RUN",pos=(240,425))
        self.run.Bind(wx.EVT_BUTTON,self.onrun)
        self.cap=wx.Button(self,label="Capture",pos=(340,425))
        self.cap.Bind(wx.EVT_BUTTON,self.oncap)
        self.testcomplete=wx.Button(self,label="Test Complete",pos=(440,425))
        self.testcomplete.Bind(wx.EVT_BUTTON,self.oncomplete)
        self.action=self.label_2_combo.GetValue()
        self.xmax=len(work.rt) if len(work.rt)>100 else 100
        self.xmin=self.xmax-100
        self.myfig=mfigure.Figure(dpi=50)
        self.axes=self.myfig.add_subplot(111)
        self.axes.set_xbound(lower=self.xmin,upper=self.xmax)
        self.canvas=FigureCanvas(self,-1,self.myfig)
        self.canvas.SetPosition((400,100))  
        self.toolbar=NavigationToolbar(self.canvas)
        self.toolbar.Realize()
        self.toolbar.SetPosition((400,75))
        tw,th=self.toolbar.GetSizeTuple()
        fw,fh=self.canvas.GetSizeTuple()
        self.toolbar.SetSize(wx.Size(fw,th))
        self.toolbar.update()
        self.animator=anim.FuncAnimation(self.myfig,self.animator,interval=1000,repeat=True)
        self.SetupScrolling()
    def onok(self,event):
        self.mode=self.label_0_combo.GetValue()
        self.noc=int(self.label_1_combo.GetValue())
        work.noc=self.noc
        self.action=self.label_2_combo.GetValue()
        if (self.action=='Web'):
            work.action=Value('i',0)
        elif(self.action=='Download'):
            work.action=Value('i',1)
        elif(self.action=='Video'):
            work.action=Value('i',2)
        else:
            self.label_2=wx.StaticText(self,-1,"Please restart & select proper Action",(40,475))
            self.Close()
        self.nos=int(self.label_3_combo.GetValue())
        work.nos=Value('i',self.nos)        
        self.filesize=self.label_4_combo.GetValue()
        if (self.filesize=='small-files'):
            work.low=Value('i',0)
            work.high=Value('i',1)
        elif (self.filesize=='0to1kb'):
            work.low=Value('i',1)
            work.high=Value('i',2)
        elif (self.filesize=='10kb'):
            work.low=Value('i',2)
            work.high=Value('i',3)
        elif (self.filesize=='20kb'):
            work.low=Value('i',3)
            work.high=Value('i',4)
        elif (self.filesize=='50kb'):
            work.low=Value('i',4)
            work.high=Value('i',5)
        elif (self.filesize=='70kb'):
            work.low=Value('i',5)
            work.high=Value('i',6)
        elif (self.filesize=='100kb'):
            work.low=Value('i',6)
            work.high=Value('i',7)
        elif (self.filesize=='200kb'):
            work.low=Value('i',7)
            work.high=Value('i',8)
        elif (self.filesize=='500kb'):
            work.low=Value('i',8)
            work.high=Value('i',9)
        elif (self.filesize=='700kb'):
            work.low=Value('i',9)
            work.high=Value('i',10)
        elif (self.filesize=='1mb'):
            work.low=Value('i',10)
            work.high=Value('i',11)
        elif (self.filesize=='2mb'):
            work.low=Value('i',11)
            work.high=Value('i',12)
        elif (self.filesize=='video1.2mb'):
            work.low=Value('i',12)
            work.high=Value('i',13)
        elif (self.filesize=='video2.2mb'):
            work.low=Value('i',13)
            work.high=Value('i',14)
        elif (self.filesize=='video2mb'):
            work.low=Value('i',14)
            work.high=Value('i',15)
        elif (self.filesize=='video3mb'):
            work.low=Value('i',15)
            work.high=Value('i',16)
        elif (self.filesize=='allfiles'):
            work.low=Value('i',0)
            work.high=Value('i',16)
        else:
            self.label_2=wx.StaticText(self,-1,"Please restart & select proper file size",(40,475))
            self.Close()
        self.rampuptime=int(self.label_5_combo.GetValue())
        work.rampuptime=(self.rampuptime/1000)
        self.mytime=self.label_6_combo.GetValue()
        if (self.mytime=='1minute'):
            self.testtime=60.0
        elif (self.mytime=='5minutes'):
            self.testtime=300.0
        elif (self.mytime=='10minutes'):
            self.testtime=600.0
        elif (self.mytime=='15minutes'):
            self.testtime=900.0
        elif (self.mytime=='30minutes'):
            self.testtime=1800.0
        elif (self.mytime=='1hour'):
            self.testtime=3600.0
        elif (self.mytime=='2hours'):
            self.testtime=7200.0
        elif (self.mytime=='3hours'):
            self.testtime=10800.0
        elif (self.mytime=='4hours'):
            self.testtime=14400.0
        elif (self.mytime=='5hours'):
            self.testtime=18000.0
        elif (self.mytime=='6hours'):
            self.testtime=21600.0
        elif (self.mytime=='10hours'):
            self.testtime=36000.0
        elif (self.mytime=='12hours'):
            self.testtime=43200.0
        elif (self.mytime=='15hours'):
            self.testtime=54000.0
        elif (self.mytime=='18hours'):
            self.testtime=64800.0
        elif (self.mytime=='24hours'):
            self.testtime=86400.0
        elif (self.mytime=='Mode is Request Based'):
            work.end_time=0
        else:
            self.label_2=wx.StaticText(self,-1,"Please restart & select proper test time",(40,475))
            self.Close()
        self.nor=self.label_7_combo.GetValue()
    def oncancle(self,event):
        sys.exit()
    def oncap(self,event):
        os.system("gnome-terminal -e 'tcpdump -ni eth0 port 80 -w cap.pcap'")
    def onrun(self,event):
        time.sleep(1)
        self.scriptstart=float(time.time())
        self.mode=self.label_0_combo.GetValue()
        if (self.mode=='Time Based'):
            work.end_time=time.time()+self.testtime
            thread.start_new_thread(work.time_func, ())
        elif(self.mode=='Request Based'):
            work.number_of_requests=int(self.nor)
            thread.start_new_thread(work.requests_func, ())
    def oncomplete(self,event):
        self.label_2=wx.StaticText(self,-1,"All work Done..!! To generate traffic again, Please restart the script ",(40,475))  
        x=len(work.rt)
        y=work.scriptend-self.scriptstart
        self.result.SetLabel("Errors=%d/%d"%(work.error_count.value,x))
        self.tresult.SetLabel("%f"%y)
    def animator(self,i):
        self.axes.cla()
        self.axes.set_ylabel("Response Time")
        self.axes.set_xlabel("Number of Files")
        return self.axes.plot(work.rt)
class DemoFrame(wx.Frame):
    def __init__ (self):
        wx.Frame.__init__(self,None,wx.ID_ANY,"Python_Scripts",size=(800,500))
        self.mypanel=TabPanel1(self)
        self.SetDoubleBuffered(True)
        self.Layout()
        self.Centre()
        self.Show()
    def onexit(self,event):
        sys.exit()
if __name__=='__main__':
    app=wx.App(False)
    frame=DemoFrame()
    frame.Show()
    app.MainLoop()
找到了解决办法, 使用wx.calllater而不是为图形设置动画,也就是说,不要使用间隔时间为1000毫秒的funcanimation,首先调用simple绘制画布的plotting函数,然后在该函数中提供wx.calllater,它在每1000毫秒后调用自己 例如

main_函数():
plot_函数()
绘图功能(自身):
wx.CallLater(1000,self.plot_函数)

我相信这是因为使用了多处理模块。我在[某处]()读到wxpython和多处理/线程不能同时进行:(这里的代码太多了。您所有的绘图命令都需要在拥有gui的进程的主线程上运行。还可以考虑使用ipython并行。我尝试从主线程运行绘图,现在图形继续运行,但gui的其他部分(即其他按钮和其他文本控件等)现在挂起。
main_function():
    plot_function()
plot_function(self):
    <plotting of graph>
    wx.CallLater(1000,self.plot_function)