0

new to python new to twisted

My team wants me to make some existing code run in a seperate thread.

I've come up with a fictional example:

from twisted.internet import threads, reactor from twisted.internet.defer import inlineCallbacks from time import sleep class SomeClass(object): def __init__(self): self.working = False def set_working(self, is_working): self.working = is_working print 'Flag set to {}'.format(is_working) @inlineCallbacks def do_worker_thread(self): # I want to make this call on the main thread self.set_working(True) # I want to do all this garbage on a separate thread and keep trucking on the main thread # This mimics some calls in the real code. There is a call to deferToThread and a try # except block there. def thread_proc(): try: for i in range(0, 100): print 'Step %d starting'.format(i) self.execute_step(i) except Exception: print 'An exception happened' reactor.callInThread(thread_proc) # When the worker thread is done, I want to call back 'on_thread_work_done' def execute_step(self, num): sleep(num) print 'Worker thread: %d'.format(num) def on_thread_work_done(self): """I want to be called back when the worker thread is done""" self.set_working(False) @inlineCallbacks def do_main_thread(self): for c in range(ord('a'), ord('z')+1): sleep(c) print 'Main thread: {}'.format(c) if __name__ == "__main__": someClass = SomeClass() result = someClass.do_worker_thread() result.addCallback(someClass.do_main_thread()) reactor.run() 

The stuff on do_worker_thread currently runs on the main thread. I put a comment in there were I want it to run in a seperate thread. It is important that do_worker_thread returns immediately.

I expect the output to look something like:

Flag set to True Step 0 starting Main thread: a Worker thread: 0 Worker thread: 1 Main thread: b Worker thread: 2 Main thread: c ... 

How can I alter what's in do_worker_thread, such that my set_working calls are on the main thread and it isn't set to False until the worker thread is done its work?

2 Answers 2

1

Try giving this a shot. It uses callFromThread() to schedule the work on the main thread.

from twisted.internet import threads, reactor from twisted.internet.defer import inlineCallbacks, returnValue from time import sleep class SomeClass(object): def __init__(self): self.working = False def set_working(self, is_working): self.working = is_working print 'Flag set to {}'.format(is_working) @inlineCallbacks def do_worker_thread(self): # I want to make this call on the main thread self.set_working(True) # I want to do all this garbage on a separate thread and keep trucking on the main thread # This mimics some calls in the real code. There is a call to deferToThread and a try # except block there. def thread_proc(): try: for i in xrange(0, 10): print 'Step {} starting'.format(i) self.execute_step(i) except Exception: print 'An exception happened' yield threads.deferToThread(thread_proc) # When the worker thread is done, I want to call back 'on_thread_work_done' self.on_thread_work_done() returnValue(17) def execute_step(self, num): sleep(1) print 'Worker thread: {}'.format(num) def on_thread_work_done(self): """I want to be called back when the worker thread is done""" self.set_working(False) def do_main_thread(self): for i in [chr(x) for x in range(ord('a'), ord('z')+1)]: print 'Main thread: {}'.format(i) sleep(1) def thread_done(self, result): print 'Thread done: {}'.format(result) if __name__ == "__main__": someClass = SomeClass() # Schedule the threaded work result = someClass.do_worker_thread().addCallback(someClass.thread_done) # Schedule the main thread work reactor.callFromThread(someClass.do_main_thread) reactor.run() 
Sign up to request clarification or add additional context in comments.

Comments

0

You can use either callFromThread or blockingCallFromThread.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.