我有一个python GUI应用程序,它使用来自通过ctypes调用的.so / .dll的长时间运行的函数。
我正在寻找一种与函数进行通信的方法,当它在一个单独的线程或进程中运行时,我可以请求它提前终止(这需要在返回部分结果之前在C端进行一些工作)。我想这需要某种信号接收或读取管道,但我希望尽可能简单。
您认为解决此类问题的最佳方法是什么?我可以在python和C端更改代码。
答案 0 :(得分:2)
这里有两个部分你需要回答:一个是如何在两个进程(你的GUI和执行函数的进程)之间进行通信,另一个是如何更改你的函数以便它响应异步请求( “哦,我被告知要回报我所得到的任何东西”。
解决第二个问题的答案可能会决定第一个问题的答案。你可以通过信号来做(在这种情况下,你得到一个信号处理程序来控制进程,可以在别处查找更详细的指令,并在将控制返回到你的函数之前更改你的内部数据结构),或者你可以拥有你的函数监视命令的控制接口(每毫秒,检查是否有命令等待,如果有,请查看它是什么)。
在第一种情况下,您需要ANSI C信号处理(signal(),sighandler_t),在第二种情况下,您可能需要管道或类似物(pipe()和select())。
答案 1 :(得分:2)
你提到你可以改变C和Python方面。为了避免在C中编写任何套接字或信号代码,最简单的方法是将大型C函数分解为3个较小的独立函数,这些函数执行设置,一小部分工作和清理。工作包应该在大约1毫秒到1秒的运行时间之间,以在响应性和低开销之间取得平衡。面对不断变化的数据大小,将计算分解为这样的组块可能很困难,但是在单个大功能中也会遇到同样的挑战。
在Python中编写一个工作进程,通过ctypes调用这三个函数。让工作进程检查Queue对象是否有来自GUI的消息以提前停止计算。确保使用非阻塞Queue.get_nowait调用而不是Queue.get。如果工作进程发现要提前退出的消息,请调用C清理代码并返回部分结果。
答案 2 :(得分:0)
如果您正在使用* nix在C程序中注册SIGUSR1或SIGINT的信号处理程序,那么从Python使用os.kill发送信号。
答案 3 :(得分:0)
你说的是:信号和管道。
它不一定非常复杂,但是如果你使用现有的结构,那么与你尝试自己的结构相比,它会更容易。