2011-01-09 23 views
26

私は、バックグラウンドでPythonスクリプトを実行して、60秒ごとにタスクを繰り返す方法が不思議でした。 &を使って何かをバックグラウンドに置くことができるのは分かっていますが、このケースではそれは圧倒的でしょうか?効率的なPythonデーモン

ループをやって60秒待ってからもう一度ロードすると思っていましたが、それについては何か気になります。

+1

それはあなたが望むものによって異なります。頻繁に繰り返すようにタスクをスケジュールする場合は、cronを見てください。 – Falmarri

答えて

7

あなたのアイデアは、あなたが望むものとほぼ同じだと思います。例:

import time 

def do_something(): 
    with open("/tmp/current_time.txt", "w") as f: 
     f.write("The time is now " + time.ctime()) 

def run(): 
    while True: 
     time.sleep(60) 
     do_something() 

if __name__ == "__main__": 
    run() 

time.sleep(60)を呼び出すと、プログラムは60秒間スリープ状態になります。その時間が経過すると、OSはあなたのプログラムを起動させ、do_something()関数を実行し、それをスリープ状態に戻します。あなたのプログラムが眠っている間、非常に効率的に何もしていません。これは、バックグラウンドサービスを作成するための一般的なパターンです。実際には、コマンドラインからこれを実行するには

、あなたは&を使用することができます。

$ python background_test.py & 

これを実行すると、スクリプトからの任意の出力は、あなたからそれを開始したものと同じターミナルに移動します。あなたはこれを回避するために出力をリダイレクトすることができます:シェルで&を使用して

$ python background_test.py >stdout.txt 2>stderr.txt & 
+0

ありがとう、これは私が探していたものです。私が知っているプログラミングのビットと部分はJavascriptから来て、タイマーで何かをしようとすると悪夢に変わった! –

+1

ログアウトしてもデーモンを継続したい場合は、nohup(例えば 'nohup python background_test.py')を見ることができます – Foon

+1

' python-daemon'を使ってこれを行う簡単な方法があります。 "標準デーモンプロセスライブラリ":http://stackoverflow.com/a/8375012/462302 – aculich

5

はおそらく、グレッグが説明するように死んで最も簡単な方法です。

しかし、実際に強力なデーモンを作成したい場合は、os.fork()コマンドを調べる必要があります。

Wikipediaから例:

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

import os, time 

def createDaemon(): 
    """ 
     This function create a service/Daemon that will execute a det. task 
    """ 

    try: 
    # Store the Fork PID 
    pid = os.fork() 

    if pid > 0: 
     print 'PID: %d' % pid 
     os._exit(0) 

    except OSError, error: 
    print 'Unable to fork. Error: %d (%s)' % (error.errno, error.strerror) 
    os._exit(1) 

    doTask() 

def doTask(): 
    """ 
     This function create a task that will be a daemon 
    """ 

    # Open the file in write mode 
    file = open('/tmp/tarefa.log', 'w') 

    # Start the write 
    while True: 
    print >> file, time.ctime() 
    file.flush() 
    time.sleep(2) 

    # Close the file 
    file.close() 

if __name__ == '__main__': 

    # Create the Daemon 
    createDaemon() 

そして、あなたがdoTask()ブロック内で必要なものは何でもタスク入れることができます。

&を使用してこれを起動する必要はなく、実行を少しカスタマイズすることができます。

83

デーモンを作成する代わりに、代わりにpython-daemonを使用してください。 python-daemonは、標準のデーモンプロセスライブラリPEP 3143の正常に動作するデーモン仕様を実装しています。

私は、この質問に対する受け入れられた答えに基づいてサンプルコードを含めました。コードはほとんど同じに見えますが、重要な根本的な違いがあります。 python-daemonを使用しない場合は、&を使用してプロセスをバックグラウンドで実行し、nohupを実行し、シェルを終了するときにプロセスが終了しないようにする必要があります。代わりに、このプログラムを実行すると、自動的に端末から切り離されます。例えば

python background_test.py 

をそしてここ&の不在に注意してください。

import daemon 
import time 

def do_something(): 
    while True: 
     with open("/tmp/current_time.txt", "w") as f: 
      f.write("The time is now " + time.ctime()) 
     time.sleep(5) 

def run(): 
    with daemon.DaemonContext(): 
     do_something() 

if __name__ == "__main__": 
    run() 

は、実際にそれを実行します。

また、this other stackoverflow answerは、python-daemonを使用することの多くの利点を詳細に説明しています。

+1

あなたは驚くかもしれませんが、PEPの著者と図書館の著者は同じ人です。そう、はい、ライブラリは非常によくPEPを実装:) – Reishin

+0

あなたは "この他のstackoverflow答え"と言うが、質問ではなく、答えにリンクします。あなたがリンクしている質問に対する選択された答えは(このコメントの時点で)pythonデーモンを使用しません。たぶんhttps://stackoverflow.com/a/688448/117471を意味するのでしょうか? –