首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从基于gunicorn的web会话终止异步多处理线程

从基于gunicorn的web会话终止异步多处理线程
EN

Stack Overflow用户
提问于 2015-08-05 08:41:24
回答 2查看 2K关注 0票数 2

我使用Django为多核科学计算库创建了一个基于浏览器的图形用户界面,使用gunicorn作为see服务器(也请参阅从Django视图启动多核背景进程)。我将图书馆的功能称为:

代码语言:javascript
运行
复制
p = multiprocessing.Process(target=library_function, args=())
p.start()
print("test")

库函数处理多核逻辑本身,所以我在这里还使用多处理模块的目的是使用户能够终止进程(通过p.terminate())。然而,这一做法目前不起作用。我的假设是,我还需要p.join()来终止library_function()调用的任何内容。问题是,当我在p.join()之后调用p.start()时,进程似乎不再异步运行,即在示例中,即"test“没有立即打印出来。但是,在我的用例中,异步是绝对必需的。

有没有人提示(1)在后台运行进程,(2)仍然允许用户终止进程?

更新

下面是noxdafox的评论,这是我现在的快速而肮脏的解决方案:

代码语言:javascript
运行
复制
import psutil, signal, os, multiprocessing

# start process
p = multiprocessing.Process(target=library_function, args=())
p.start()

# stop process
for child in psutil.Process(p.pid).children(recursive=True):
    child.kill() # kill child processes
os.kill(p.pid, signal.SIGKILL) # kill parent process
p.join() # kills parent zombie process
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-05 11:44:55

调用p.terminate()会向进程发送SIGTERM信号。默认情况下,Python解释器会在这些信号上退出,但在某些情况下它不会:

  • 该进程正在覆盖SIGTERM信号的默认行为。这可能是Django框架本身设置的(我不知道它是内部的)。
  • 进程正在等待C/C++调用返回,无法对SIGTERM信号作出反应。

p.join()阻塞调用方,直到子进程未结束为止。必须始终调用它,以便清理过期的子进程。您之所以失去并行性,是因为您启动了新进程并等待它完成。

如果要在单独的进程上生成任务并安全地终止它,可以使用鹅卵石库:

代码语言:javascript
运行
复制
from pebble import process

@process.concurrent
def library_function( ... ):
    return

task = library_function( ... )
task.cancel()

更简单。

代码语言:javascript
运行
复制
from pebble import process

task = process.concurrent(target=library_function, args=( ... ))
task.cancel()

编辑:您想要做的事情是不同的,您现在尝试的方式有点危险。

在子进程(从multiprocessing.Process而不是subprocess)中运行一个进程池并不是最优的。此外,终止包含池的进程将导致所有工作进程的泄漏。

来自平行文件,它是在幕后使用的进程池的实现。

用“Ctrl”中断多进程作业

要实现这一点,您可以向子进程发送一个SIGINT信号,并查看它是否实际工作。

代码语言:javascript
运行
复制
import multiprocessing, signal, os

p = multiprocessing.Process(target=library_function, args=())
p.start()

# stop the job    
os.kill(p.pid, signal.SIGINT)
p.join()
票数 1
EN

Stack Overflow用户

发布于 2015-08-05 08:53:14

对于您的第一个问题,我建议异步任务处理芹菜将是更好的选择。

使用芹菜,您可以让用户撤销这些任务:

结果= add.apply_async(args=2,2,countdown=120) result.revoke()

通过撤销,芹菜工作不会执行任务。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31827503

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档