sunshinekitty
sunshinekitty

Reputation: 2375

Python 3.3 - Send variable to thread

I'm not sure if this is best practice or anything, but I have a thread running that activates every 5 seconds checking for a parameter in a list, outside of that thread I have a while loop running that will insert the parameter into the list using a function outside of the while loop (this part works as it should), however the list doesn't update inside of the thread, how would I send this into the thread?

IE

def addtolist():
    mylist.extend([variable])

def myfunction():
    while True:
        if time.time() > 5 + last_time:
            last_time = time.time()
            print(mylist[0]) # doesn't print anything
        time.sleep(1)

if __name__ == "__main__":
    count_job = Thread(target = myfunction, args = ())
    count_job.start()

while True:
    variable = "Look, a fly!"
    addtolist()
    time.sleep(7)

I mean it's a quite bit more complicated than that and way too long to paste in here but this is the part that I've just added that isn't working, what am I doing wrong?

Upvotes: 0

Views: 207

Answers (2)

Raydel Miranda
Raydel Miranda

Reputation: 14360

I recommend you another aproach for implementing threads that has some state. Do not use globals, use threading.Thread inheritance instead.

For instance, your problem can be solved this way:

import threading
import time


class MyThread(threading.Thread):

    def __init__(self, some_list=None):
        super(MyThread, self).__init__()
        self.list = some_list if some_list is not None else []
        self.event = threading.Event()     # Used for stop the thread

    def run(self):
        while not self.event.isSet():
            # Do your thread thing here.
            time.sleep(1)
            print(self.list)


    def add_elem(self, elem):
        self.list.append(elem)  # Extend or append, is up to you.

    def stop(self):
        self.event.set()


if __name__ == '__main__':

    thread = MyThread()     # Thread instance.
    thread.start()          # Start the thread.
    thread.add_elem(10)     # Add some element.
    time.sleep(3)           # Wait 3 secs.
    thread.add_elem(100)    # Add another element.
    time.sleep(3)           # Wait 3 secs.
    thread.stop()           # Stop thread.

This way you can even add more "behaviour" to your thread, you might add functions like remove, sort, etc...

On the other hand, if you are executing tasks that get executed past some time(5 secs in your case) you should consider use Timers Objects

Upvotes: 1

isedev
isedev

Reputation: 19641

Your thread function exits immediately... it performs a single check of the time, prints the first element of mylist depending on the initial value of last_time and exits.

Aside from the fact that your example code does not show how/where the variables are initialised, your thread function needs to look something like this:

def myfunction():
    while True: # loop forever
        if time.time() > 5 + last_time:
            last_time = time.time()
            print(mylist[0]) # doesn't print anything
        time.sleep(1) # wait for one second for mylist to be updated, yield to main thread

Note if you do not add a sleep in the thread, it will wait in a busy loop without returning control to the main thread (and consume a great deal of CPU).

Also, note that the thread will always print the same value (the first element of mylist). Since addtolist appends to the end of the list, new values will not be displayed. You may want to change print(mylist[0]) to print(mylist[-1]) to display the last inserted elements.

Finally, there are much better ways of doing this. See docs.python.org/3.3/library/threading.html under section 17.1.5. Condition Objects.

Upvotes: 2

Related Questions