I am trying to write a python script which registers a function as a listener for certain events. However, by the time the listener callback function gets called, the python process has ended, since it is just a short script. What is the best way to keep the python process running so that the callback function can be run when it gets an update?
In case it is relevant, I am trying to do this to get state updates from a drone running ardupilot. Whenever the drone's attitude changes, I want my callback function to be run.
Thanks in advance for any help!
You can achieve that using a good while loop that updates your listener function so long as your set criteria evaluate to true.
Related
I have a PostgreSQL function that wraps around a plpython3u function.
Now everytime I run that function and want to cancel it mid running, the function only stops running once the Python function finishes, which defeats the whole purpose of cancelling. This is especially problematic if the Python function goes into a never ending loops.
Is there a way to force cancellation on the python function, or any setup that makes it listen to the cancellation command?
(I'm using DBeaver)
Thank you.
Not wanting my GUI to freeze, I've decided to use a thread for a file operation. Currently I'm using thread.start_new_thread(self.openFile, (filepath, self.openedFile)) to do so, with self.openedFile being my callback method. Inside self.openFile it is just invoked using callback(success).
But unfortunately I couldn't figure out how to execute my callback in the main thread instead of the newly created one. This is required as the GUI cannot be modified from another thread.
I really appreciate all your help!
The thread owning the GUI will have to periodically check a Queue.Queue instance on which other threads can put work requests (e.g a callback function and arguments for it).
How easy or hard it is to insert such checks within a GUI's main loop is 100% dependent on exactly what GUI framework you're using.
For example if you're using Tkinter, the after method of widgets lets you do such periodic checks, as explained e.g at Run an infinite loop in the backgroung in Tkinter .
I have a very basic Tkinter application that I'm trying to set to automatically refresh. I am using threading.Timer to trigger a function called go at the end of which cocalls the timer to reset it to run again.
def SetTimer():
t=threading.Timer(5,go())
t.start
SetTimer()
I've spent most of my afternoon trying to resolve this but I can't seem to figure out what I'm doing wrong. Based upon the other questions I've read I understand that each instance creates a separate thread with the timer, but why isn't it waiting for the time to elapse prior to triggering the function.
Use:
t=threading.Timer(5,go)
Note the go rather than go(). The parentheses tell Python to call the function. In contrast, go is a function object. Functions are "first-class" objects in Python; they can be passed to functions just like any other object.
Python evaluates the arguments to a function before calling the function. So using go() calls the go before calling threading.Timer. The value returned by go() gets sent to Timer, which is not what you want.
Note that all Tkinter UI code should be called from a single thread. For this reason, using Tkinter's root.after method is probably a better choice for what you want to do. The after method schedules a function to be called by Tkinter's mainloop. Here are some examples using after:
Tkinter and Threads
A rotating image
I am implementing a Python plugin that is part of a larger C++ program. The goal of this program is to allow the user to input a command's actions in Python. It currently receives a string from the C++ function and runs it via the exec() function. The user can then use an API to affect changes on the larger C++ program.
The current feature I am working on is a pause execution feature. It needs to remember where it is in the code execution as well as the state of any local variables, and resume execution once a condition has been met. I am not very familiar with Python, and I would like some advice how to implement this feature. My first design ideas:
1) Using the yield command.
This seemed to be a good idea at the start since when you use the next command it remembers everything I needed it to, but the problem is that yield only returns to the previous level in the call stack as far as I can tell. So if the user calls a function that yields it will simply return to the user's code, and not the larger C++ program. As far as I can tell there isn't a way to propagate the yield command up the stack???
2) Threading
Create a main python thread that creates a thread for each command. This main thread would spawn a thread for each command executed and kill it when it is done. If it needs to be suspended and restarted it could do so through a queue of locks.
Those were the only two options I came up with. I am not sure the yield function would work or is what it was designed to do. I think the Threading approach would work but might be overkill, and take a long time to develop. I also was looking for some sort of Task Module in Python, but couldn't find exactly what I was looking for. I was wondering if anyone has any other suggestions as I am not very familiar with Python.
EDIT: As mentioned in the comments I did not explain what needs to happen when the script "Pauses". The python plugin needs to allow the C++ program to continue execution. In my mind this means A) returning if we are talking about a single threaded approach, or B) Sending a message(Function call?) to C++
EDIT EDIT: As stated I didn't fully explain the problem description. I will make another post that has a better statement of what currently exists, and what needs to happen as well as providing some sudo code. I am new to Stack Overflow, so if this is not the appropriate response please let me know.
Whenever a signal is sent in Python, execution is immediately paused until whatever signal handler function is being used is finished executing; at that point, the execution continues right where it left off. My suggestion would be to use one of the user-defined signals (signal.SIGUSR1 and signal.SIGUSR2). Take a look at the signal documentation here:
https://docs.python.org/2/library/signal.html
At the beginning of the program, you'd define a signal handler function like so:
def signal_pause(signum, frame):
if signum == signal.SIGUSR1:
# Do your pause here - function processing, etc
else:
pass
Then in the main program somewhere, you'll switch out the default signal handler for the one you just created:
signal.signal(signal.SIGUSR1, signal_pause)
And finally, whenever you want to pause, you'll send the SIGUSR1 signal like so:
os.kill(os.getpid(),signal.SIGUSR1)
Your code will immediately pause, saving its state, and head to the signal_pause function to do whatever you need to do. Once that function exits, normal program execution will resume.
EDIT: this assumes you want to do something sophisticated while you're pausing the program. If all you want to do is wait a few seconds or ask for some user input, there are some much easier ways (time.sleep or input respectively).
EDIT EDIT: this assumes you're on a Unix system.
If you need to communicate with a C program, then sockets are probably the way to go.
https://docs.python.org/2/library/socket.html
One of your two programs acts as the socket server, and the other connects to it as the socket client. When you want the C++ program to continue, you use socket.send() to transmit a continue message. Then your Python program would use socket.recv(), which will cause it to wait around until it receives a message back from the C++ program.
If you need two programs to send signals to each other, this is probably the safest way to go about it.
I am trying to implement a program that will be able to execute 2 functions asynchronously, e.g. let each function be triggered regardless of whether the other one is running and how long its been running for.
I know python supports threading, but all examples I have seen call functions in the script, so there is a predetermined order and time separation between the functions.
My question is how to get passed that and trigger the functions myself whenever I am ready.