簡體   English   中英

Python多處理意外阻塞

[英]Python multiprocessing blocking unexpectedly

我正在Linux環境下使用apache和modpython運行python腳本。 它集成在一個允許文件處理的Web工具中。 我的腳本中包含文件處理的部分可能會有很長的執行時間。 在我的代碼的原始版本中,腳本等待處理文件,最后它返回一些帶有鏈接的html以下載生成的文件。

submit.html

<html>
    <body>
        <form enctype="multipart/form-data" action="./my_script.py/main" method="post">
            <div> <input type="file" name="file"> </div>
            <div> <input type="submit" value="Upload"> </div>
    </body>
</html>

my_script.py

def main(file):
    process(file)
    return "<p> Download your file <a href='./%s'></a>", % file

def process(file)
    #some file treatment here, and a resulting file is stored in current directory

我想寫一個功能,允許用戶通過電子郵件接收生成的文件。 在那種情況下,一旦他上傳了他的文件,我想將他重定向到一個頁面,他可以繼續使用網絡工具,而他的文件正在服務器端處理,因此用戶不是Unix分叉。 我已經使用這3個選項進行了多次測試,但我總是被運行腳本阻止。 根據我的理解,多處理最適合我的情況,所以我試過這個:

my_script.py

def main(file, receiver_mail_address):
    p = Process(target=process_and_email, args=(file, receiver_mail_address)
    p.start()
    return "<p> The resulting files will be emailed to you at %s.</p>" % receiver_mail_address

def process_and_email(file, receiver_mail_address):
    #some file processing here, and emailing. these functions work perfectly as expected.

在這種情況下,我跳過了p.join()步驟,這是在python docs中說的

“阻塞調用線程,直到調用join()方法的進程終止或直到發生可選超時。”

但在我的情況下,它仍然被阻止。 這意味着我必須等到我的進程p在到達return語句之前結束。 我怎么能這樣做?


編輯:

我試圖更改為subprocess模塊。 所以我將process_and_email函數放入一個名為process_and_email.py的新文件中,並修改了主腳本:

my_script.py

def main(file, receiver_mail_address):
    directory = os.path.firname(__file__)
    path = os.path.join(directory, 'process_and_email.py')

    subprocess.Popen(['python2.7', path, file, receiver_mail_address], shell=True)

    return "<p> The resulting files will be emailed to you at %s.</p>" % receiver_mail_address

我仍然遇到同樣的問題:在process_and_email.py文件完全執行之前,我無法訪問return語句。

發生這種情況是因為在所有非守護進程子進程完成他們正在進行的工作之前,您的父進程不會退出。 因此,在您的情況下,即使main已完成, process_and_email需要在腳本退出之前完成。 您可以使子進程成為守護進程,這將允許父腳本立即退出,但它會在退出之前終止工作進程,這也不是您想要的。

我認為更好的選擇是使用subprocess進程模塊生成一個單獨的Python腳本來在后台進行處理。 這樣您的父腳本就可以退出,並使工作進程保持運行狀態。

Web應用程序中使用的常見模式是維護全局隊列,例如, beanstalkd具有一個名為beanstalkc的漂亮Python接口。 然后,您可以將這些作業提交到隊列,並擁有一個單獨的程序/進程監視,它可以對隊列中的項進行排隊和處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM