代码之家  ›  专栏  ›  技术社区  ›  Algorias

在python中与长时间运行的任务通信

  •  1
  • Algorias  · 技术社区  · 15 年前

    我有一个python gui应用程序,它使用一个通过ctypes调用的.so/.dll中的长时间运行函数。

    我正在寻找一种方法,当函数在单独的线程或进程中运行时与它进行通信,这样我就可以请求它提前终止(这需要在返回部分结果之前在C端进行一些工作)。我想这需要某种从管道接收或读取的信号,但我希望尽可能简单。

    你认为解决这类问题的最佳方法是什么?我能够在Python和C端更改代码。

    4 回复  |  直到 15 年前
        1
  •  2
  •   Anthony Towns    15 年前

    这里有两个部分您需要回答:一个是如何在两个进程(您的GUI和执行函数的进程)之间进行通信,另一个是如何更改您的函数,以便它响应异步请求(“哦,我被告知只返回我得到的东西”)。

    算出第二个问题的答案可能会口述第一个问题的答案。你可以通过信号来实现(在这种情况下,你可以得到一个信号处理程序来控制进程,可以在其他地方寻找更详细的指令,在将控制返回到你的函数之前改变你的内部数据结构),或者你可以让你的函数监视命令的控制接口(每毫秒,检查这是一个等待的命令,如果有的话,看看它是什么)。

    在第一种情况下,您需要使用ANSI C信号处理(signal(),sighandler_t),在第二种情况下,您可能需要使用管道或类似的管道(pipe()和select())。

        2
  •  2
  •   Theran    15 年前

    您提到可以同时更改C和Python两个方面。为了避免在C中编写任何套接字或信号代码,最好将大型C函数分解为3个较小的单独函数,这些函数执行设置、一小部分工作和清理。工作包的运行时间应该在1毫秒到1秒之间,以在响应能力和低开销之间取得平衡。面对不断变化的数据大小,将计算拆分成这样的块可能很难,但在一个同样执行I/O的大型函数中,您将面临同样的挑战。

    用python编写一个工作进程,通过ctypes调用这3个函数。让工人流程检查 Queue 对象,用于从GUI发送消息以提前停止计算。确保使用非阻塞queue.get_Nowait调用而不是queue.get。如果工作进程发现要提前退出的消息,请调用C清理代码并返回部分结果。

        3
  •  0
  •   brotchie    15 年前

    如果您是on*nix,请在C程序中为sigusr1或sigint注册一个信号处理程序,然后从python使用os.kill发送信号。

        4
  •  0
  •   MarkusQ    15 年前

    你说过:信号和管道。

    它不必太复杂,但是如果你使用一个现有的结构,它会比你尝试滚动自己的结构容易得多。