モブ沢工房

プログラミングとかLinux関連(特にOSSのグラフィックツール関連)とかレトロゲームとか3Dプリンタやら日曜大工等、色々。

PythonによるCGIでバックグラウンド処理

pythonならos.fork()で簡単♪

と思いきや、全然動きませんでした…いや動くことは動くんだけど、「重い処理」を切り離してブラウザ画面だけは即座に戻る、という目論見とは異なり、ブラウザが十数秒間待つという感じ。

sys.stdout.flush() とかしても全然無駄でして…

色々調べまくってわかりましたが、stdoutとかを継承しているため子プロセスが終わるまでhttpdが待ってるんですね。

それはいいんですがどうやったらstdioを継承させずにすむのか?全然わからず。os.dup2を使うということに辿り着き、ようやくできました!

    pid=os.fork()
    if pid==0:
        # to let the main process go through,set stdios as os.devnull at child
        ndi=open(os.devnull,'r')
        ndo=open(os.devnull,'a+')
        nde=open(os.devnull,'a+',0)
        os.dup2(ndi.fileno(),sys.stdin.fileno())
        os.dup2(ndo.fileno(),sys.stdout.fileno())
        os.dup2(nde.fileno(),sys.stderr.fileno())
        something_heavy_processing() # 重い処理
    else:
        pass

ようやくですよ…一日これで潰した…お陰でmultiprocessingとsubprocessにも親しめたから、いいかw