如何通过Apache生成Python2.5进程并立即在Windows下返回

时间:2011-03-12 22:22:06

标签: python apache2 subprocess

我有两个Python脚本,一个用子进程启动另一个

invoke.py:

import subprocess
p = subprocess.Popen(['python', 'long.py'])
print "Content-Type: text/plain\n"
print "invoked (%d)" % (p.pid)

longtime.py:

import time
import os
print "start (%d)" %(os.getpid())
time.sleep(10)
print "end (%d)" %(os.getpid())

当我从shell执行invoke.py时,它立即返回,longtime.py在后台运行(适用于Windows和Linux)。如果我通过Web界面(Apache CGI)调用invoke.py,它可以在Linux 下运行,但不能在Windows 机器上运行,那么网站就会卡住,只有在longtime.py完成后才会返回。

如何配置Python子流程或Apache以在Windows下获得相同的行为?差异是什么?

也许Windows上的Apache配置有些不同但我找不到东西。

Linux:Debian,Python2.5.2,Apache2.2.9
Windows:WinXP,Python2.7,Apache2.2.17

也许你也有一个更好的设计方法(因为我现在做的有点尴尬)。

为什么?:我在网络服务器上有一个脚本需要很长时间才能计算(longtime.py)。我想通过Web界面激活执行。网站应该立即返回,longtime.py应该在后台工作并将输出写入文件。稍后,来自Web界面的请求将检查文件是否已生成并读取输出。我不能使用常见的云提供者,因为他们不支持多线程。此外,我无法在Web服务器上安装守护程序处理程序,因为进程具有最大运行时间。

1 个答案:

答案 0 :(得分:0)

我已经在Windows XP和OSX 10.6.6(shell)上测试了下面的代码,它在不等待子进程完成的情况下退出。

<强> invoke.py:

from subprocess import Popen, PIPE
import platform


if platform.system() == 'Windows':
    close_fds=False
else: 
    close_fds=True

p = Popen('python long.py', stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=close_fds, shell=True)
print "Content-Type: text/plain\n"
print "invoked (%d)" % (p.pid)

<强> long.py

import time
import os
print "start (%d)" %(os.getpid())
time.sleep(10)
print "end (%d)" %(os.getpid())

<强>更新 在Windows 7 + Apache 2.2.17 + Python 2.7 + mod_wsgi 3.3。

上测试

mod_wsgi.so文件可以从here下载。 文件应重命名为mod_wsgi.so并放在apache模块文件夹中。

<强> invoke.wsgi: 来自子进程导入Popen,PIPE 导入平台

def application(environ, start_response):
    if platform.system() == 'Windows':
        close_fds=False
    else: 
        close_fds=True

    p = Popen('python "C:\testing\long.py"', stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=close_fds, shell=True)

    status = '200 OK'
    output = "invoked (%d)" % (p.pid)    
    response_headers = [('Content-type', 'text/plain'), ('Content-Length', str(len(output)))]
    start_response(status, response_headers)

    return [output]

long.py 文件保持不变。

httpd.conf

的更改

追加wsgi模块:

LoadModule wsgi_module modules/mod_wsgi.so

将目录添加到配置

<Directory "C:/testing">
    AllowOverride None
    Options None
    Order allow,deny
    Allow from all
</Directory>

将url链接到目录

Alias /testapp "C:\testing"

使用wsgi app链接网址

WSGIScriptAlias /testapp "C:\testing\invoke.wsgi"

重新启动网络服务器。 转http://server_name/testapp 应该显示进程ID并退出。