ozzymado
ozzymado

Reputation: 998

How to pass a list of objects to a thread function

I have to pass a list of objects to a function that executes in a thread in python. I need to be able to call functions of those objects, such as animal.bite(). I created a generic test class:

class test_class:    
    def f(self):
        print 'hello'

and created a list of these objects:

test_object = test_class()
new_object = test_class()
strlist = [test_object, new_object]

and have a function that creates a thread if one hasn't already been created:

def threadScheduler(*stringlist):
    global lock #variable defined elsewhere, makeshift resource lock
    if not lock:
        print "creating thread"
        lock = True
        thread = threading.Thread(name='heartbeat', target=threadWorkLoad, args=(stringlist,))
        thread.start()

This is the function threadWorkLoad:

def threadWorkLoad(*stringlist):
    global lock
    for item in stringlist:
        print 'in thread', item.f()
    time.sleep(2)
    lock = False
    return

and this is the main loop:

for x in range(0,10):
    print 'in main thread', strlist[0].f()
    threadScheduler(strlist)
    time.sleep(1)

What I would like to do is to be able to call the function f() on the objects in the list in threadWorkLoad, but currently I get the error AttributeError: 'tuple' object has no attribute 'f'

If I replace those objects with strings, the code works the way I want it to. But I need to be able to do the same thing with objects. How do I do this in python?

EDIT:

Some other things I tried -

I changed the creation of the thread in threadScheduler to thread = threading.Thread(name='heartbeat', target=threadWorkLoad, args=[stringlist]) with no luck.

I also tried to put in the following statement as the first line of threadScheduler:

print 'in scheduler', stringlist[0].f()

and I get the same error. It seems like the issue is related to passing a list objects as a function parameter.

I should also clarify that we are using Python 2.5.2.

Upvotes: 2

Views: 2613

Answers (1)

ozzymado
ozzymado

Reputation: 998

Two changes had to be made for this to work (thanks to Scott Mermelstein):

In the main loop, threadScheduler(strlist) had to be changed to threadScheduler(*strlist). I verified this by adding the following line to the threadScheduler() function:

print 'in scheduler', stringlist[0].f()

and was able to successfully call f() only after I added the asterisk. I'm unsure of why the argument had to be passed this way, though.

Additionally, I had to change

thread = threading.Thread(name='heartbeat', target=threadWorkLoad, args=(stringlist,))

to

thread = threading.Thread(name='heartbeat', target=threadWorkLoad, args=tuple(stringlist))

Then I was able to successfully call f() for each object in the list in the threadWorkLoad() function.

Upvotes: 1

Related Questions