0

when i used the following code using single thread time is 49.7 secs but as i increase the number of threads as below

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

the execution time is also increasing.

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

The output for single thread is:

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

3
 execution time of worker1 is: 49.2760000229

for two thread's is:

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

Why is it happening like that. Can anyone explain? Also what is that SockThread? TIA

dinece
  • 113
  • 1
  • 2
  • 12

1 Answers1

1

Your threads are fighting with eachother on one core due to the Global Interpreter Lock. The Global Interpreter Lock prevents more than one python thread from running at a time, even on a multi-core system. Thus, to execute multiple cpu-bound tasks in parallel, it is necessary to use processes (from the multiprocessing module) instead of threads.

Also, the SockThread appearing in your list is internal to IDLE.

pppery
  • 3,731
  • 22
  • 33
  • 46
  • oh thank you. will try multiprocessing then and see. – dinece May 01 '16 at 11:18
  • should i use both multiprocessing and multithreading together or only multiprocessing alone ? – dinece May 02 '16 at 06:33
  • There is no reason to use the `threading` module for multiple cpu-bound tasks. It is just slower. Only use `multiprocessing` – pppery May 02 '16 at 12:59
  • Every python module is documented online. The documentation for `multiprocessing` is located at https://docs.python.org/2/library/multiprocessing.html – pppery May 11 '16 at 21:07
  • Thank You. I've seen this documentation but it wasn't clearly documented.Thats why i asked for a good documentation. :) – dinece May 12 '16 at 04:18
  • In the sense multiprocessing documentation related to wxpython – dinece May 12 '16 at 04:41