0

there. I was creating a program and ran into a problem that baffles me and my understanding of basic code (or my understanding of my eyesight).

According to me this code should print out

Test

immediately as the program starts and then when ext() is called from Timer thread the loop variable will change to False, essentially returning false on the if statement and not continuing to print out 'Test'.

But even though ext() is called(I tested this) the if statement gets on being called and loop does not change to False.

from threading import Timer, Thread
from time import sleep

loop = True

def hello():
    while True:
        if loop == True:
            print('Test')
            sleep(0.5)

def ext():
    loop = False

th = Thread(target=hello)
th.start()

t = Timer(5, ext())
t.start()

Please help as I have been stuck for this for several hours.

Simon Erasmus
  • 134
  • 12

2 Answers2

0

You need to specify loop as a global variable. In ext() it thinks that you are defining a new variable called loop while you actually want to modify the global variable. So the correct code would be this one:

from threading import Timer, Thread
from time import sleep

loop = True

def hello():
    while True:
        if loop == True:
            print('Test')
            sleep(0.5)

def ext():
    global loop
    loop = False

th = Thread(target=hello)
th.start()

t = Timer(5, ext)
t.start()

You also need to change the one before last line and instead of calling ext pass it to Timer

afsafzal
  • 592
  • 5
  • 15
  • I'm running it. It works. The thing is that it remains in the `while True` loop because there's no sleep or return from that function. But that was not the question – afsafzal Sep 23 '16 at 21:16
  • Hi, thanks for the replies. Btw does the use of global change at all between python 2.7 and python 3? – Simon Erasmus Sep 23 '16 at 21:20
  • It calls `ext()` immediately from the main thread, not after 5 seconds from a timer thread. The code should print `Test` 10 times. No timer thread is created. – tdelaney Sep 23 '16 at 21:20
  • @tdelaney You are right. I was just talking about his problem with global variable modification. There are other problems with the code too. But thanks you, I updated the answer. – afsafzal Sep 23 '16 at 21:24
  • `global` is the same in 3.x as before. Bindings to a global name can occurs at either module scope or withing a function, in any other. `global` declarations (only needed within functions) do not 'create a variable'. They alter the meaning of assignment statements within a function as to where the name binding takes place. – Terry Jan Reedy Sep 23 '16 at 21:38
0

You have two problems... well, three really. First, ext is referencing a local variable called loop not the global. Second, you don't really start the thread because you called the function instead of passing in its reference. Third... you no longer sleep when loop is set so your code ends up eating a full cpu in a tight loop. Fixing the first two would be

from threading import Timer, Thread
from time import sleep

loop = True

def hello():
    while True:
        if loop == True:
            print('Test')
            sleep(0.5)

def ext():
    global loop
    loop = False

th = Thread(target=hello)
th.start()

t = Timer(5, ext)
t.start()
tdelaney
  • 73,364
  • 6
  • 83
  • 116