0

當我用使用單個線程時間以下代碼是49.7秒,但正如我增加線程的數量,如下我應該如何減少在python中使用線程的執行時間?

work1=TestThread(self,"worker1") 
work2=TestThread(self,"worker2") 

的執行時間也越來越多。

import time 
import wx 
import threading 
from threading import Thread 

# Define notification event for thread completion 
EVT_RESULT_ID = wx.NewId() 

def EVT_RESULT(win, func): 
    """Define Result Event.""" 
    win.Connect(-1, -1, EVT_RESULT_ID, func) 

class ResultEvent(wx.PyEvent): 
    """Simple event to carry arbitrary result data.""" 
    def __init__(self, data): 
     """Init Result Event.""" 
     wx.PyEvent.__init__(self) 
     self.SetEventType(EVT_RESULT_ID) 
     self.data = data 

######################################################################## 
class TestThread(Thread): 
    """Test Worker Thread Class.""" 

    #---------------------------------------------------------------------- 
    def __init__(self, wxObject,name): 
     """Init Worker Thread Class.""" 
     Thread.__init__(self) 
     self.name = name 
     self.wxObject = wxObject 
     self.start() # start the thread 

    #---------------------------------------------------------------------- 
    def run(self): 
     """Run Worker Thread.""" 
     # This is the code executing in the new thread. 
     start_time=time.time() 
     print " Entering " + self.name + "\n" 
     for i in range(1000): 
      for a in range(1000): 
       for b in range(1000): 
        pass 
     print " execution time of "+ self.name +" is: " + str(time.time()-start_time) + "\n" 
     aot=1 
     wx.PostEvent(self.wxObject, ResultEvent(aot)) 

######################################################################## 
class MyForm(wx.Frame): 

    #---------------------------------------------------------------------- 
    def __init__(self): 
     wx.Frame.__init__(self, None, wx.ID_ANY, "Tutorial") 

     # Add a panel so it looks the correct on all platforms 
     panel = wx.Panel(self, wx.ID_ANY) 
     self.displayLbl = wx.StaticText(panel, label="Amount of time since thread started goes here") 
     self.btn = btn = wx.Button(panel, label="Start Thread") 

     btn.Bind(wx.EVT_BUTTON, self.onButton) 

     sizer = wx.BoxSizer(wx.VERTICAL) 
     sizer.Add(self.displayLbl, 0, wx.ALL|wx.CENTER, 5) 
     sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5) 
     panel.SetSizer(sizer) 

     # Set up event handler for any worker thread results 
     EVT_RESULT(self, self.updateDisplay) 

    #---------------------------------------------------------------------- 
    def onButton(self, event): 
     """ 
     Runs the thread 
     """ 
     self.displayLbl.SetLabel("Thread started!") 
     work1=TestThread(self,"worker1") 
     print threading.enumerate() 
     print threading.activeCount() 
     btn = event.GetEventObject() 
     btn.Disable() 

    #---------------------------------------------------------------------- 
    def updateDisplay(self, msg): 
     """ 
     Receives data from thread and updates the display 
     """ 
     t = msg.data 
     if (t==1): 
      self.btn.Enable() 

#---------------------------------------------------------------------- 
# Run the program 
if __name__ == "__main__": 
    app = wx.App() 
    frame = MyForm().Show() 
    app.MainLoop() 

輸出爲單獨的線程是:

Entering worker1 
[<_MainThread(MainThread, started 9360)>, <Thread(SockThread, started daemon 4984)>, <TestThread(worker1, started 5776)>] 

3 
execution time of worker1 is: 49.2760000229 

兩個線程的是:

Entering worker1 
Entering worker2 
[<_MainThread(MainThread, started 8880)>, <Thread(SockThread, started daemon 8280)>, <TestThread(worker1, started 5788)>, <TestThread(worker2, started 12240)>] 


4 
execution time of worker2 is: 113.527999878 

execution time of worker1 is: 114.292000055 

爲什麼會發生這樣的。誰能解釋一下?那麼SockThread又是什麼? TIA

+2

受CPU限制的Python程序不會因GIL導致多線程性能提升。 – thebjorn

+0

哦,有什麼辦法可以提高性能嗎? – dinece

+2

使用多個進程。 –

回答

1

由於Global Interpreter Lock,您的線程正在與一個核心上的海誓山盟對抗。 Global Interpreter Lock可防止多個python線程同時運行,即使在多核系統上也是如此。因此,要並行執行多個cpu綁定任務,有必要使用進程(來自multiprocessing模塊)而不是線程。

另外,出現在您的列表中的SockThreadIDLE之內。

+0

哦謝謝你。將嘗試多處理,然後看看。 – dinece

+0

我應該同時使用多處理和多線程,還是隻使用多處理? – dinece

+0

沒有理由對多個cpu綁定任務使用'threading'模塊。它只是慢一點。只能使用'multiprocessing' – ppperry