Callbacks between threads - python

There is one process, which creates thread in the middle of process's work. Now we have Main thread and Thread2. Main thread does some job and it coudln't wait for an event. Thread2 - is an infinite loop, which is waiting for a signal. When signal comes, thread2 should send command (e.g. print str) to Main thread.
Is there any way to pass the command from thread2 to Main thread without making Main thread waiting? I mean something like interrupts or callbacks.
And if there comes a signal to thread2, then thread2 interrupt Main thread work and force it to do my command (print str), or thread2 send command with callback, which goes to queue and runs when its turn in queue.

Related

Python multithreading: Is the thread that is notified through condition.notify() assured to take the lock?

Question in the title:
When a thread goes on the wait() function, it goes into wait-c, and when another thread that currently has acquired the same lock of the same condition as the first thread executes the notify() function, the first thread that was in wait-c is now in wait-l, so it's waiting for the second thread to release the lock for it.
But if there are other threads waiting on that same lock, is the thread that was notified assured to take the lock when the thread that used notify() releases the lock at the end?

Pausing the Main Thread in Python

I currently have a main function being run in Python on the main thread. This main function creates an additional thread called ArtificialPlayerControllerSynthesis to run a background process. I would like to pause the main thread for a second or two to allow the background process to finish before continuing in the main thread. However, all solutions to this issue that I can find, such as from Pausing a thread using threading class, require passing an event object as an argument to the thread I want to pause. This is not possible in my case, or would at the very least require restructuring my code and moving my main function to a new thread. Is it possible to simply pause the main thread? I am new to Python and threading, thanks in advance for yall's help.
thread = threading.Thread(target=some_func)
thread.start()
do_some_stuff_now()
thread.join() # blocks until thread finishes
do_some_stuff_later()

How to break signal.pause in python?

I have a main thread which starts child threads and then does signal.pause()
def run(self):
for thread in (some_thread, some_other_thread, another_thread):
thread.start()
signal.pause()
On completion of work of child threads, the main thread doesn't terminate until it receives SIG_TERM signal.
I can't use join method to wait for child threads to complete since on doing so my program is not listening to external kill signals.
What is the best way to make the main thread come out of signal.pause()?
One way could be to send kill signal from any one of the child threads, but that won't be a good approach.

Checking the status of a python thread from a seperate function

Currently I am able to run a thread and update label items in a GUI (pyqt5) as the thread is running. However, I want to add information on the status of the thread, i.e. when the thread starts (label updated as :'thread initiated') and when the thread ends (label updated as: 'thread complete'). The thread start update is not a problem because I can update the label as soon as the thread is initiated. However, the thread end update is somewhat more problematic since I have no way of knowing when the thread has finished. I have tried thread.join(), though this prevents dynamic update of labels when the thread is running (The GUI freezes until the thread has finished). I have tried to update the label from a separate function but with no success.
My current code (shortened):
def onbuttonpress(self):
self.label.setText('thread initiated')
self.simulation()
self.label.setText('thread finished')
def simulation(self):
def sim():
pythoncom.CoInitialize()
------code-----
self.thread = threading.Thread(target=mt)
self.thread.start()
Is there a alternative to thread.join() that works without crashing GUIs?
You can use the timeout parameter of join() to try joining, if unsuccessful, it's not ready yet.
https://docs.python.org/2/library/threading.html#threading.Thread.join
For the duration of the timeout, the GUI thread will be blocked, so set it to a small value (e.g. 1 ms). Do this check periodically (e.g. once every second) until the thread is done.
Alternatively, use the signal-slot mechanism of Qt to notify the GUI thread from the worker thread.
pyqt4 emiting signals in threads to slots in main thread
PyQt5 - How to emit signal from worker tread to call event by GUI thread

Trying to understand python multithreading

Please consider this code:
import threading
def printer():
for i in range(2):
with lock:
print ['foo', 'bar', 'baz']
def main():
global lock
lock = threading.Lock()
threads = [threading.Thread(target=printer) for x in xrange(2)]
for t in threads:
t.start()
t.join()
main()
I can understand this code and it is clear: We create two threads and we run them sequentially - we run second thread only when first thread is finished. Ok, now consider another variant:
import threading
def printer():
for i in range(2):
with lock:
print ['foo', 'bar', 'baz']
def main():
global lock
lock = threading.Lock()
threads = [threading.Thread(target=printer) for x in xrange(2)]
for t in threads:
t.start()
for t in threads:
t.join()
main()
What happens here? Ok, we run them in parallel, but what is the purpose of make main thread waiting for child threads in second variant? How it can influence on the output?
In the second variant, the ordering of execution is much less defined.
The lock is released each time through the loop in printer. In both variants, you have two threads and two loops within a thread.
In the first variant, since only one thread runs at a time, you know the total ordering.
In the second variant, each time the lock is released, the thread running may change.
So you might get
thread 1 loop 1
thread 1 loop 2
thread 2 loop 1
thread 2 loop 2
or perhaps
* thread 2 loop 1
* thread 1 loop 1
* thread 1 loop 2
* thread 2 loop 2
The only constraint is that loop1 within a given thread runs before loop 2 within that thread and that the two print statements come together since the lock is held for both of them.
In this particular case I'm not sure the call to t.join() in the second variant has an observable effect. It guarantees that the main thread will be the last thread to end, but I'm not sure that in this code you can observe that in any way. In more complex code, joining the threads can be important so that cleanup actions are only performed after all threads terminate. This can also be very important if you have daemon threads, because the entire program will terminate when all non-daemon threads terminate.
To better understand the multithreading in python, you need to first understand the relationship between the main thread and the children threads.
The main thread is the entry of the program, it is created by your system when you run your script. For example, in your script, the main function is run in the main thread.
While the children thread is created by your main thread when you instanate the Thread class.
The most important thing is how the main thread controls the children thread. Basically, the instance of the Thread is everything that the main thread know about and control over this child thread. At the time when a child thread is created, this child thread does not run immediately, until the main thread call start function on this thread instance. After the start the child thread, you can assume that the main thread and the child thread is running parallelly now.
But one more important thing is how the main thread knows that the task of child thread is done. Though the main thread knows nothing about how the task is done by the child thread, it does be aware of the running status of the child thread. Thread.is_alive can check the status of a thread by the main thread. In pratice, the Thread.join function is always used to tell the main thread wait until the child thread is done. This function will block the main thread.
Okay, let's examine the two script you are confused with. For the first script:
for t in threads:
t.start()
t.join()
The children threads in the loop are started and then joined one by one. Note that start does not block main thread, while join will block the main thread wait until this child thread is done. Thus they are running sequentially.
While for the second script:
for t in threads:
t.start()
for t in threads:
t.join()
All children threads are started in the first loop. As the Thread.start function will not block the main thread, all children threadings are running parallelly after the first loop. In the second loop, the main thread will wait for the task done of each child thread one by one.
Now I think you should notice the difference between these two script: in the first one, children threads running one by one, while in the second script, they are running simultaneously.
There are other useful topics for the python threading:
(1) How to handle the Keyboard Interrupt Exception, e.g., when I want to terminate the program by Ctrl-C? Only the main thread will receive the exception, you have to handle the termination of children threads.
(2) Multithreading vs Multiprocessing. Although we are saying that threading is parallel, it is not the real parallel in CPU level. So if your application is CPU intensive, try multiprocessing, and if your application is I/O intensive, multithreading maybe sufficient.
By the way, read through the documentation of python threading section and try some code may help you understand it.
Hope this would be helpful. Thanks.

Categories