Chandler
Chandler

Reputation: 57

Creating a class instance on a separate thread while still being able to access its methods in python

In my current code I am trying to make a class that gets created in a separate thread. I want this class to be on its own thread because it does many performance heavy things. I also have other classes that need to access the methods inside the class I want on a separate thread. Here is an example of what I want to be able to do:

import thread

class ClassInThread:
    def __init__(self, obj)
        self.obj = obj

     def getObj():
        return self.obj

class NormalClass:
    def __init__(self):
        self.obj = None

    def setObj(self, obj):
        self.obj = obj     

classOne = thread.start_new_thread(ClassInThread, (12,))
classTwo = NormalClass()

classTwo.setObj(classOne.getObj())

This example doesn't work because when the new thread is created it doesn't return the ClassInThread instance. How can I make this work?

Upvotes: 1

Views: 3285

Answers (2)

Paul Seeb
Paul Seeb

Reputation: 6166

You can create the class in your main program and retain a reference to that class. Then you can create a thread using a class method which is, I assume, IO intensive. Python threads are primarily helpful in IO bound situations. If you are processor bound you should look at multiprocessing.

Be careful about accessing class attributes that are modified in the threaded service as you might cause collisions. The way to work around this is with locks (like mutex in C)

import threading

class ClassInThread:
    def __init__(self, obj)
        self.obj = obj
        self.run_event = threading.Event()
        self.run_event.set()

     def getObj(self):
        return self.obj

     def run_heavy_service(self):
        while self.run_event.is_set():
            time.sleep(5)
            print "Serving"

     def kill(self):
        self.run_event.clear()

class NormalClass:
    def __init__(self):
        self.obj = None

    def setObj(self, obj):
        self.obj = obj     

classOne = ClassInThread(12)
classTwo = NormalClass()

threaded_IO_bound_proc = threading.Thread(target = classOne.run_heavy_service)
threaded_IO_bound_proc.start()

classTwo.setObj(classOne.getObj())

Upvotes: 0

dano
dano

Reputation: 94961

You should use the threading module instead of the thread module. The thread module is a lower-level thread API, which normally shouldn't be used.

With the threading module, you can do this:

import threading

class ClassInThread(threading.Thread):
    def __init__(self, obj)
        self.obj = obj

     def getObj(self):
        return self.obj

     def run(self):
         pass
         # This method is what is executed in a separate thread when you call classOne.start() below. You should implement it.


class NormalClass(object):
    def __init__(self):
        self.obj = None

    def setObj(self, obj):
        self.obj = obj     

classOne = ClassInThread(12)
classOne.start() # starts the thread
classTwo = NormalClass()

classTwo.setObj(classOne.getObj())

Upvotes: 3

Related Questions