Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有没有一种简单的方法可以从Python CGI脚本启动后台任务而不必等待它终止?_Python_Windows_Cgi - Fatal编程技术网

有没有一种简单的方法可以从Python CGI脚本启动后台任务而不必等待它终止?

有没有一种简单的方法可以从Python CGI脚本启动后台任务而不必等待它终止?,python,windows,cgi,Python,Windows,Cgi,也就是说,在Windows中 我想这个问题的答案是我需要创建一个Windows服务。对于我正在尝试做的事情来说,这似乎是可笑的重量级 我只是想在这里为我的经理制作一个小原型,我不会负责生产它。。。事实上,它甚至可能永远不会被生产;这可能只是一些研究人员玩弄的东西 我有一个CGI脚本,它接收一个要上传的文件,将其存储到一个临时位置,然后启动一个后台进程对该文件进行一些认真的数字处理。然后,一些Javascript代码会调用其他CGI脚本来检查状态并根据需要更新页面 所有这些都可以工作,除了该死的w

也就是说,在Windows中

我想这个问题的答案是我需要创建一个Windows服务。对于我正在尝试做的事情来说,这似乎是可笑的重量级

我只是想在这里为我的经理制作一个小原型,我不会负责生产它。。。事实上,它甚至可能永远不会被生产;这可能只是一些研究人员玩弄的东西

我有一个CGI脚本,它接收一个要上传的文件,将其存储到一个临时位置,然后启动一个后台进程对该文件进行一些认真的数字处理。然后,一些Javascript代码会调用其他CGI脚本来检查状态并根据需要更新页面

所有这些都可以工作,除了该死的web服务器不会关闭连接,只要子进程正在运行。我做了一些搜索,在Unix上的答案似乎是将其作为一个守护进程,但我现在被困在Windows上,我想答案是将其作为Windows服务?!?你知道,启动一个该死的进程,然后关闭服务器连接,这看起来非常重

那真的是唯一的办法吗

编辑:好的,在这里发现了一个漂亮的小黑客(这家伙给出的选择(3)):

我能够修改它,使它更简单,虽然这是一个klugey解决方案,它是完美的快速和肮脏的小原型,我正试图使

因此,我最初让我的主脚本这样做:

subprocess.Popen("python.exe","myscript.py","arg1","arg2")
正如我所描述的,这是行不通的。相反,我现在让我的主脚本发出一点点Javascript,在文档完全加载后运行:

$("#somecrap").load("launchBackgroundProcess.py", {arg1:"foo",arg2:"bar"});
然后launchBackgroundProcess.py执行subprocess.Popen

此解决方案永远不会扩展,因为它在后台任务运行的整个过程中仍然保持浏览器连接打开。但是,由于我正在开发的这个小东西可能有一天最多会有两个同时使用的用户(即使我怀疑),所以资源并不重要。这允许用户查看主页并获取Javascript更新,即使仍然有一个http连接由于没有好的理由而挂起


谢谢你的回答!如果有人要求我将其产品化,我会参考Profane推荐的资源。

最简单但不是最有效的方法就是运行另一个python可执行文件

from subprocess import Popen 
Popen("python somescript.py")

您只需使用“开始”windows命令调用
系统
。这样,您的python脚本就不会等待已启动程序的完成。

如果您对windows编程没有太多经验,并且不想阅读MSDN文档——我不怪您——您可能想尝试获取一份Mark Hammond的cannonical指南,了解python和windows的所有内容。在许多这样反复出现的问题上,它从不会过时。和使用每个平台解决方案启动流程不同,您最好使用win32process模块。哈蒙德书的第17章对此进行了详细的介绍,但您可能需要下载pywin ide(我认为它捆绑在windows扩展中,您可以从pypi下载),并查看它在python的windows api上的帮助文档。下面是一个使用api的示例,来自我最近从事的一个项目。事实上,它可能会做一些你想做的事情。你可能想把重点放在CreationFlags上。特别是,win32process.u进程“通常用于在后台执行控制台程序”。不过,还有许多其他标志可用,并且可以方便地包装

    if subprocess.mswindows:
        su=subprocess.STARTUPINFO()
        su.dwFlags |= subprocess._subprocess.STARTF_USESHOWWINDOW
    process = subprocess.Popen(['program', 'flag', 'flag2'], bufsize=-1,
              stdout=subprocess.PIPE, startupinfo=su)

CGI脚本在标准输出重定向的情况下运行,直接重定向到TCP套接字或管道。通常,在句柄及其所有副本关闭之前,连接不会关闭。默认情况下,子流程将继承句柄的副本

有两种方法可以防止连接等待子进程。一个是防止子流程继承句柄,另一个是子流程在启动时关闭其句柄副本

如果子流程使用Perl,我认为可以非常简单地关闭句柄:

close(STDOUT);

如果要阻止子进程继承句柄,可以使用SetHandleInformation函数(如果您有权访问Win32 API)或在调用CreateProcess时将bInheritHandles设置为FALSE。或者,在启动子进程之前关闭句柄。

不确定它是否有效,但您是否尝试生成单独的线程来启动后台进程?然后,您的主函数可以在不等待再次加入线程的情况下返回…这也会有同样的问题。需要明确的是:Python脚本本身并不是在等待流程返回,我的脚本继续运行,完成了它的所有业务,没有问题。但是Apache会保持http连接打开,直到子进程终止。这就是我已经在做的事情。由于Windows管理进程的方式,即使以这种间接方式启动子进程,父进程也不会消失,直到子进程终止。因此,web服务器保持连接打开,只是坐在那里。+1没有意识到这已经是你的方法;如果您更愿意采用这种方法,而不是重写流程本身,那么这里的答案可能很容易实现。只是用分离的进程标志启动它。不知道start是这样工作的;如果您不需要更多的定制(在win32process中)并且不需要任何Popen功能,那么这是创建独立于脚本的新流程的最快方法吗?这似乎也有同样的问题。我在谷歌上看到的一个问题——我发现这些答案也有同样的问题——是人们似乎不理解这一点