12-16-2021 01:27 PM
Lets a assume I am calling a python node instance. The VI has to wait until the python node has finished executing before continuing with other logic. What happens if the python function/code that the LabVIEW python node calls hangs (ex: cannot timeout accessing a resource or gets stuck in an infinite loop)? In an ideal world, the python node would have some timeout input. Is there a way to force stop the python node or the VI that is calling the python node without force closing LabVIEW? I gave it a try (see attached, LabVIEW 2020) with no success, and my initial assumption is it will not work because LabVIEW is calling a DLL (or some other python/Windows resource) that needs to complete before returning to the VI (see Timeout on a DLL Call for more information).
Here is some example python code that will never complete:
def my_func(my_num: int = 0, my_num2: int = 0):
while True:
pass
print(1 + my_num + my_num2)
return 1 + my_num + my_num2
If there is a way around this I would be interested to know, or at the very least to have. some way of knowing the python code has caused LabVIEW to hang. Thanks
12-17-2021 03:55 AM - edited 12-17-2021 04:16 AM
Yes, it's a dll call so there's no way out.
Best next thing is to start a VI dynamically to do the job. If that VI doesn't return an answer within the TO, stop waiting for it (while it keeps on running). This will become a problem when your program stops, because it won't if the dynamic VIs are still waiting on DLLs to finish.
Or you could pass a timeout to the Python code, but that might not be that easy. Either check the TO in a loop, or maybe Python can start a task and wait for it or terminate it.
Coroutines and Tasks — Python 3.10.1 documentation seems to indicate that there are options.
12-17-2021 04:57 AM - edited 12-17-2021 05:01 AM
Python coroutines can be aborted. But the LabVIEW Python node doesn't support them AFAIK. So you would have to create a Python wrapper that starts the problematic routine as a coroutine and implements the timeout after which it aborts the coroutine.
You could even seperate that into a more generic Python library with one function launching the coroutine and returning some form of handle or cookie to it to LabVIEW and another Python function in that library that can be used to monitor and possibly abort the coroutine by passing it the handle you received earlier.
I'm not sure about the current state of coroutines in Python but in pre 3.0 versions it was still a bit of a moving target to use, as there were changes in the implementation and use of them between the different versions. It was definitely not something I felt comfortable to add to LabPython to support directly.
12-17-2021 12:05 PM
This is in line with what what I was thinking, thanks. Call and forget the VI and then offload some responsibility to whoever wrote the python function.
12-17-2021 01:21 PM
@forward_079 wrote:
This is in line with what what I was thinking, thanks. Call and forget the VI and then offload some responsibility to whoever wrote the python function.
I'd say you don't need both.
Having Python abort the function (or making the function stop at TO) would be a better solution.
If a dynamic VI hangs in a DLL, closing your application becomes a problem. It only solves part of the problem.
12-18-2021 08:32 AM
I was not really suggesting to Call and forget the VI containing the Python node. That can work one time but gives problems if you need to call this function again before the first has returned or you want to terminate your program.
My proposal was to create the wrapper in Python by using Python coroutines. Then call the wrapper functions from LabVIEW.
The main problem is simply that Python really is a different environment and you can’t easily go from one environment to stop something in the other directly. Even if the LabVIEW Python Node would support coroutine execution, there are many things in the Python function you call that way that will still prevent LabVIEW from taking control of this coroutine such as the Python routine calling a synchronous Python function or a function located in a DLL.
12-20-2021 03:36 PM
My proposal was to create the wrapper in Python by using Python coroutines. Then call the wrapper functions from LabVIEW.
I have not used coroutines with python, but having looked through the python docs creating a wrapper using coroutines makes the most sense for ensuring that the python function called completes.
I was not really suggesting to Call and forget the VI containing the Python node. That can work one time but gives problems if you need to call this function again before the first has returned or you want to terminate your program.
Thanks for pointing this out
12-21-2021 03:35 AM
@forward_079 wrote:I was not really suggesting to Call and forget the VI containing the Python node. That can work one time but gives problems if you need to call this function again before the first has returned or you want to terminate your program.
Thanks for pointing this out
It would help to minimize the symptoms. It would not fix the problem.
At some point the problem will (e.g. when closing the application\LabVIEW) come back to you for sure. Probably when it's most inconvenient, like when a deadline is near.
04-01-2022 07:42 PM - edited 04-01-2022 07:43 PM
I have a similar problem. A LabVIEW program runs some Python scripts. Some of them could take pretty long time, let's say 4 to 5 minutes. Sometimes the user wants to about the execution, i.e., stop the Python node.
It looks like this is not a straightforward operation. Initially I was thinking about exchanging messages between the Python script and LabVIEW, but this seems more work compared to just killing the niPythonHost process from LabVIEW. It doesn't seem very nice, but it will work.
I could get the PID of the niPythonHost by calling a simple Python script right after creating the Python session reference, and if I need to abort, i.e., force the node to stop, I could kill this PID and close the reference.
Does anyone think that there is a problem with this approach? I am talking about Windows only.