0

「autorun.py」と「main.py」の 2 つのスクリプトがあります。Linux システムの autorun にサービスとして「autorun.py」を追加しました。完璧に動作します!

ここで私の質問は次のとおりです。自動実行スクリプトから「main.py」を起動したい場合、「main.py」は永久に実行されますが、「autorun.py」も終了しません! だから私がするとき

sudo service autorun-test start

コマンドも終了しません!

「main.py」を実行して終了するにはどうすればよいですか?「autorun.py」がパラメータ「stop」で起動されたときに「main.py」を停止するにはどうすればよいですか? (これは私が思う他のすべてのサービスの仕組みです)

編集:

解決:

if sys.argv[1] == "start":
    print "Starting..."
    with daemon.DaemonContext(working_directory="/home/pi/python"):
        execfile("main.py")
else:
    pid = int(open("/home/pi/python/main.pid").read())
    try:
        os.kill(pid, 9)
        print "Stopped!"
    except:
        print "No process with PID "+str(pid)
4

1 に答える 1

1

まず、システム デーモンを作成しようとしている場合は、ほぼ確実にPEP 3143daemonに従いたいと考えており、ほぼ確実にモジュールを使用してそれを実行したいと考えています。

自動実行スクリプトから「main.py」を起動したい場合、「main.py」は永久に実行されますが、「autorun.py」も終了しません!

あなたはそれをどのように実行しているかを言いませんでした。子として起動main.pyして待機する (または、さらに悪いことに、同じプロセスでimport/ execfile/etc. を試行する) ことを行っている場合、それはできません。autorun.py起動してデタッチするmain.py(または外部ツールを介して間接的に行う) か、main.py起動時にデーモン化する必要があります。

「autorun.py」がパラメータ「stop」で起動されたときに「main.py」を停止するにはどうすればよいですか?

autorun何らかの形式のプロセス間通信 (IPC) と、使用する適切な IPC チャネルを見つけるための何らかの方法が必要です。

ネットワーク サーバーを構築している場合、クライアントとして接続するのが正しい答えかもしれません。しかし、それ以外の場合、最も簡単なことはkill、シグナルを使用したプロセスです。

モジュールを使用している場合、daemonシグナルをコールバックに簡単にマップできます。または、クリーンアップが必要ない場合はSIGTERM、デフォルトで突然終了する を使用してください。どちらにも当てはまらない場合は、カスタム シグナル ハンドラーをセットアップする必要があります (そして、そのハンドラー内で何か役に立つことを行います。たとえば、メイン コードが定期的にチェックするフラグを設定します)。

シグナルを送信するプロセスをどのように知ることができますか? これを行う標準的な方法はmain.py、起動時にその PID を pidfile に記録することです。その pidfile を読み取り、そこに指定されているプロセスを通知します。(その PID を持つプロセスがないためにエラーが発生した場合、それはデーモンが何らかの理由で既に終了したことを意味します。おそらく、未処理の例外、または segfault が原因である可能性があります。それをログに記録したい場合がありますが、「停止」を扱います) " それ以外の場合は成功します。) 繰り返しますが、 を使用してdaemonいる場合は、pidfile の処理が行われます。そうでない場合は、自分で行う必要があります。

お使いのコンピュータに付属しているデーモンのサービス スクリプトを参照してください。それらはおそらくすべて Python ではなく bash で書かれていますが、何をしているのかを理解するのはそれほど難しくありません。または... それらの 1 つをスケルトンとして使用するだけです。この場合、 bash の知識はまったく必要ありません。名前を検索して置換するだけです。

ディストリビューションに LSB スタイルの init 関数がある場合は、この例のようなものを使用できます。これは必要以上に多くのことを行いますが、すべての詳細の良い例です。または、この例のようなものを使用して、すべてをゼロから実行します。これは pidfile の管理とサービス スクリプトからのバックグラウンド処理 (非デーモン プログラムをデーモンに変える) を行っていますが、これはdaemon適切に使用している場合は必要なく、SIGTERM の代わりに SIGHUP を使用しています。init.d サービス スクリプトの他の例については、Google で検索できます。

ただし、自分のシステムでこれを実行しようとしている場合は、ディストリビューションの /etc/init.d を調べるのが最善の方法です。そこには何十もの例があり、それらの 90% はデーモンの名前を除いてまったく同じです。

于 2013-04-05T01:27:38.613 に答える