Higeath
Higeath

Reputation: 561

Multiplethreading pauses the second thread

I'm new to threading and even newer to python I went through multiple questions and for some reason I cannot get it right.

I have an application that displays LED (number) State (true/false) now I want it to blink so it turns on waits 2 seconds then turns off waits 2 seconds. I display what state it is on after each change. I have created 2 of those LEDs one has delay between blinks of 2 seconds one 5 so my predicted output of those two would be like:

LED: 15 State: True
LED: 16 State: True
LED: 16 State: False
LED: 15 State: False

and instead I get

LED: 15 State: True
LED: 15 State: False
LED: 16 State: True
LED: 16 State: False

And the code itself:

import time
from threading import Thread

class ledController(Thread):
    #static variables
    def __init__(self, GPIO, state=False): # x = " " - Default variable if user leaves it empty
        self.GPIO = GPIO
        self.state = state #Default LED state is off
    def ledSwitch(self):
        self.state = not self.state
    def ledON(self):
        self.state = True
    def ledOFF(self):
        self.state = False

    def ledBlink(self, duration):
        self.ledON()
        print(self.ledDetails())
        time.sleep(duration)
        self.ledOFF()
        print(self.ledDetails())
        time.sleep(duration)

    def ledDetails(self):
        return "LED: " + str(self.GPIO) + " State: " + str(self.state)


redLED = ledController(15)
blueLED = ledController(16, True)

redLED.ledBlink(5)
blueLED.ledBlink(2)

Upvotes: 0

Views: 36

Answers (2)

EbraHim
EbraHim

Reputation: 2359

You didn't used multi-threading functionality at all. You just derived the Thread module methods in you class, but not used them.

Here is another way of implementing multi-thread program using thread module:

import time
import thread

class ledController():
    #static variables
    def __init__(self, GPIO, state=False): # x = " " - Default variable if user leaves it empty
        self.GPIO = GPIO
        self.state = state #Default LED state is off
    def ledSwitch(self):
        self.state = not self.state
    def ledON(self):
        self.state = True
    def ledOFF(self):
        self.state = False

    def ledBlink(self, duration):
        self.ledON()
        print(self.ledDetails())
        time.sleep(duration)
        self.ledOFF()
        print(self.ledDetails())
        time.sleep(duration)

    def ledDetails(self):
        return "LED: " + str(self.GPIO) + " State: " + str(self.state) + '\n'


redLED = ledController(15)
blueLED = ledController(16, True)


try:
   thread.start_new_thread( redLED.ledBlink, (5, ) )
   thread.start_new_thread( blueLED.ledBlink, (2, ) )
except:
   print "Error: unable to start thread"

Works as below:

>>> ================================ RESTART ================================
>>> 
>>> LED: 15 State: True
LED: 16 State: True
LED: 16 State: False
LED: 15 State: False

Quoted from here:

And here is a sample for using Thread sub-classes (as you did it):

import threading
import time

exitFlag = 0

class myThread (threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):
        print "Starting " + self.name
        print_time(self.name, self.counter, 5)
        print "Exiting " + self.name

def print_time(threadName, delay, counter):
    while counter:
        if exitFlag:
            threadName.exit()
        time.sleep(delay)
        print "%s: %s" % (threadName, time.ctime(time.time()))
        counter -= 1

# Create new threads
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# Start new Threads
thread1.start()
thread2.start()

print "Exiting Main Thread"

That works as below:

Starting Thread-1
Starting Thread-2
Exiting Main Thread
Thread-1: Thu Mar 21 09:10:03 2013
Thread-1: Thu Mar 21 09:10:04 2013
Thread-2: Thu Mar 21 09:10:04 2013
Thread-1: Thu Mar 21 09:10:05 2013
Thread-1: Thu Mar 21 09:10:06 2013
Thread-2: Thu Mar 21 09:10:06 2013
Thread-1: Thu Mar 21 09:10:07 2013
Exiting Thread-1
Thread-2: Thu Mar 21 09:10:08 2013
Thread-2: Thu Mar 21 09:10:10 2013
Thread-2: Thu Mar 21 09:10:12 2013
Exiting Thread-2

Upvotes: 1

tobspr
tobspr

Reputation: 8376

You are deriving your controllers from Thread, but you are not using the thread methods at all.

Because of that, all your methods are executed synchronously, and thats how the output is generated.

You should make a run() method in your derived class, and then start the thread by using .start().

Also see the documentation:

run() - Method representing the thread’s activity.

You may override this method in a subclass. The standard run() method invokes the callable object passed to the object’s constructor as the target argument, if any, with sequential and keyword arguments taken from the args and kwargs arguments, respectively.

Upvotes: 2

Related Questions