如何通过Apache的python2.5产卵过程和Windows

问题描述:

下立即返回我有两个Python脚本,一个启动另一个与子如何通过Apache的python2.5产卵过程和Windows

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 Interface(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

也许你也有一个更好的设计方法(因为它有点尴尬我该怎么办呢现在)。

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

我已经在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与目录与WSGI应用

Alias /testapp "C:\testing" 

链接URL

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

重新启动Web服务器。 去http://server_name/testapp 应用程序应该显示进程ID和退出。

+0

嗨tuscias,我已经与您的代码测试,它在外壳的作品(如以前的版本太)但如果我把从网页上的invoke.py,让Apache的执行。我也玩过Popen的参数,但总是一样的结果。我认为问题是Apache,不知道为什么。它是否适用于Apache或仅与shell协同工作? – Chris 2011-03-13 23:01:50

+0

我附加了mod_wsgi的另一个解决方案。也许这有帮助。 – tuscias 2011-03-14 08:30:30

+0

嘿谢谢指出WSGI。我修改了调用服务的结构,它对WSGI很有用! – Chris 2011-03-15 13:37:22