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() 

シングルスレッドの出力は、次のとおりです。2スレッドのための

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のために1つのコアでお互いに戦っています。グローバルインタープリタロックは、マルチコアシステム上であっても、一度に複数のPythonスレッドが実行されるのを防ぎます。したがって、複数のCPUバウンドタスクを並列に実行するには、スレッドの代わりにプロセス(multiprocessingモジュールから)を使用する必要があります。

また、SockThreadは、IDLEの内部にあります。

+0

ありがとうございます。マルチプロセッシングを試して見てみましょう。 – dinece

+0

私はマルチプロセッシングとマルチスレッドの両方を一緒に使うべきですか、あるいはマルチプロセッシングだけを使うべきですか? – dinece

+0

複数のCPUバインドタスクに 'threading'モジュールを使用する理由はありません。それはちょうど遅いです。 'マルチプロセッシング'のみを使用する – ppperry

関連する問題