Closed Overdrivr closed 9 years ago
Question is too vague, please elaborate.
I have a program which decodes serial data in a thread. When a specific frame is detected in the serial flow, I call Signal.emit (from this thread), then data is plotted, etc. Now sometimes this thread won't return and hangs on exit, and I isolated the line causing this issue to be this Signal.emit line.
I am not saying this is Signal.emit fault, instead I am starting to think what I am doing is very bad practice to emit signals from a thread, because the function connected the signal might not be thread safe.
So, to sum up: When calling emit, are the connected functions called immediatly (= in the current thread) or is the emit event put on a event list and called on the main thread later ?
Ok, is there any way we can reproduce this ?
I cannot reproduce it with this simple code:
from signalslot import Signal
import threading
import random
import queue
def callback(count,**kwargs):
print("Drawn number3 "+str(count)+" times.")
class Tester():
def __init__(self):
self.queue = queue.Queue()
self.input_thread_running = True
self.input_thread = threading.Thread(target=self.add)
self.output_thread_running = True
self.output_thread = threading.Thread(target=self.remove)
self.count = 0
self.signal = Signal(args=['count'])
self.signal.connect(callback)
self.output_thread.start()
self.input_thread.start()
def add(self):
while self.input_thread_running:
self.queue.put(random.randint(0,10))
print("Input thread finished.")
def remove(self):
while self.output_thread_running:
i = self.queue.get()
if i == 3:
self.count += 1
#print("Drawn 3")
self.signal.emit(count=self.count)
#print("Signal emitted")
print("Output thread finished.")
def stop(self):
self.input_thread_running = False
self.output_thread_running = False
self.input_thread.join()
self.output_thread.join()
if __name__ == '__main__':
t = Tester()
while t.count < 20:
pass
t.stop()
I looked at your library code and I realize my question is silly. Calling emit on a signal connected to non thread-safe function is of course non thread-safe. No magic there
In my code, the emitted signals called matplotlib drawing functions, which I just found out must not be called from secondary threads. So I guess that pretty much answer my question, the thread hanging issue must have come from there.
I'll just close it if that's fine with you, regards
Well done @Overdrivr B)
Thanks a heap for sharing your code !
Is it ok (=thread-safe) to do that ?
I suppose it is only thread safe if the called func is also thread-safe can you confirm ?
Thank you PS : Great little module, good job ;)