如何通过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和退出。
嗨tuscias,我已经与您的代码测试,它在外壳的作品(如以前的版本太)但如果我把从网页上的invoke.py,让Apache的执行。我也玩过Popen的参数,但总是一样的结果。我认为问题是Apache,不知道为什么。它是否适用于Apache或仅与shell协同工作? – Chris 2011-03-13 23:01:50
我附加了mod_wsgi的另一个解决方案。也许这有帮助。 – tuscias 2011-03-14 08:30:30
嘿谢谢指出WSGI。我修改了调用服务的结构,它对WSGI很有用! – Chris 2011-03-15 13:37:22