2011-03-12 35 views
1

下立即返回我有兩個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服務器上安裝守護程序處理程序,因爲進程的運行時間最長。

回答

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與目錄與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