Multi-threading in PyTango

Hi Community members,

I am new to PyTango and exploring how multi-threading works in Python/PyTango.

I want to do some processing in parallel when a command is invoked on the TANGO device. For this, I created a device server, with two spectrum attributes and one command. The command is executed to copy source spectrum attribute to the Target spectrum attribute, using two threads (each thread to change one element of the spectrum attribute) running in parallel.

While the threads are running, "device timed out" error is observed which pauses working of the main device (ZMQ) thread and ATKPanel/Device server becomes unresponsive.
After the custom thread's execution is completed, main ZMQ thread resumes and ATKPanel is able to reflect the changes.

The test device code and error screenshot are attached to the post.

Can anyone point me to a direction on how to resolve this issue? Is there any way to run threads in parallel without the main ZMQ thread being paused?

Thanks & Regards,
Apurva Patkar
Edited 5 years ago
I think this is a simple syntax problem: You are not running a separate thread, you are executing the function in the Thread() constructor statement. Instead, you want a reference to the function object, i.e. without parentheses.

Console output when adding threading.current_thread() to print():
Ready to accept request
on main, thread obj: <_DummyThread(Dummy-6, started daemon 10172)>
In thread 1, thread obj: <_DummyThread(Dummy-6, started daemon 10172)>
Target is: 0 0
Target is: 0 1
In thread 2, thread obj: <_DummyThread(Dummy-6, started daemon 10172)>
Target is: 1 0
Target is: 1 1
Target is: 1 2
Source attribute is copied to Target attribute.

I changed your code to:

            self.Thread1 = threading.Thread(None, self.element1_fun, 'PythonThreading') #notice missing ()
            self.Thread2 = threading.Thread(None, self.element2_fun, 'PythonThreading')
            self.Thread1.start()
            self.Thread2.start()

Output now:
Ready to accept request
on main, thread obj: <_DummyThread(Dummy-6, started daemon 5668)>
In thread 1, thread obj: <Thread(PythonThreading, started daemon 7200)>
In thread 2, thread obj: <Thread(PythonThreading, started daemon 7196)>
Source attribute is copied to Target attribute.

Target is: 0 0
Target is: 1 0
Target is: 0 1
Target is: 1 1
Target is: 1 2

No timeout on Jive device test window. In general, PyTango should be fully thread safe.

Edit: Although PyTango is thread safe, you have to think about whether your end of the code could crash the program by changing data that is read from the main thread in the meantime (e.g. if array size changes you can get all sorts of crashes). You have to make your editing thread safe and for example make reading TargetAttr return a dummy value and AttributeQuality CHANGING.
Edited 5 years ago
Hi Leonard,

Thank You for the prompt response.

I made the changes in the code and now it is working fine. "device timed out" error is not occurring and the main device (ZMQ) thread is responding while the threads are running in parallel.smile

Thanks & Regards,
Apurva Patkar
 
Register or login to create to post a reply.