0

このトピックが過去に議論されたことは知っていますが、私はリソースの使用について少し偏執的です。

私が取り組んでいる Web アプリのファイルを zip ファイルにアーカイブするジョブをキューに入れるためのデーモンを作成することを検討しています。次のように動作します。

while True:
    while morejobs():
        zipfile()
    sleep(15seconds)

バックグラウンドで常にループしているプロセスによって、どのような種類のリソースが消費されるでしょうか (zip するものが何もない場合)。気をつけることや注意することはありますか?

編集:

回答のほとんどが睡眠時間について懸念しているようです。一度に 15 ミリ秒間 (コード例で) スリープするようにやみくもに設定しました。私は実際には 15 秒にするつもりでしたが、それを反映するようにコードを「更新」しました。

再度編集:

スクリプトがスリープ状態になるのに妥当な最短時間はどれくらいですか? 5秒は低いですか?このアプリの負荷がどの程度になるか、または新しいジョブがキューに追加される頻度はわかりません。

4

8 に答える 8

4

睡眠にはオーバーヘッドはありません。Linux OSは、非常に単純な信号を使用して、スリープ状態のプロセスをウェイクアップします。

あなたが見せているのは「ビジーウェイト」のデザインパターンです。

オーバーヘッドを排除するために、あなたはやるべき仕事があるときだけ起こされることを望みます。

これを行う方法。

  1. 読むのを待ちます。

  2. select関数呼び出しを待ちます。http://docs.python.org/library/select.htmlを参照してください

  3. ロックが解除されるのを待ちます。http://docs.python.org/library/posixfile.htmlを参照してください。

これらのうち、読み取りを待つのがおそらく最も簡単です。パイプやソケットからの読み取りはあなたがやりたいことです。

あなたは「マルチライター-シングルリーダー」のデザインパターンを持っていると思います。この場合、2つの解決策の候補があります。

  1. ソケットごとに複数のリクエスト。これは、1つのソケットで接続をリッスンし、クライアントごとに専用の接続を開く単純なサーバーを作成するFTPのようなソリューションです。次に、selectを使用して、ファイルを送信しているクライアントを判別します。

  2. ソケットごとに1つのリクエスト。これは、あるソケットでリクエストを受信し、そのリクエストが大量のデータであるHTTPのようなソリューションです。リクエストがすべて終了すると、別のクライアントがリクエストを取得できるようにソケットが閉じられます。

これらの2つのケースでは、あなたは眠っていません-あなたはI/Oが完了するのを待っています。

于 2009-04-23T14:22:10.417 に答える
1

ファイルが到着するのに20秒かかり、ファイルを処理するのに5秒かかる場合(これらの数字は例です)、ファイルが次のように検出されるまでに平均でさらに7.5秒待つプロセスの害は何ですか。そこの?

スリープ状態のプロセスは、CPUへの影響を可能な限りゼロに近づける必要があります。

いいえ、私はこの側面についてはまったく気にしません。

気にする必要があるのは、失敗した場合にプロセスを自動的に再開する方法です。私は5分ごとにcronジョブ(実際の頻度の選択)を実行して、古いコピーを(丁寧に、実行中の場合にのみ)削除してから、新しいコピーを開始します。そうすれば、問題が発生した場合のダウンタイムは最大で5分になります。

古いものはファイルの処理の途中である可能性があり、回復可能でない限りそれを中断するべきではないので、私は丁寧に言います。

于 2009-04-23T14:16:01.477 に答える
1

15 秒間スリープする代わりに、新しいファイルが到着したときにジョブを再開するコールバックを用意した方がよい場合があります。

  • 利用可能なファイルを処理する
  • 60 秒ごと、または任意の間隔で新しいファイルを確認します
  • 新しいファイルが到着したら、それと最後の間隔以降に到着した可能性のある他のファイルを処理します
于 2009-04-23T14:11:03.500 に答える
1

別の方法として、プロセスの優先度を下げることができます。(私はWindowsの方法にしか慣れていません)

Windows の場合:

def setpriority(pid=None,priority=1):
    """ Set The Priority of a Windows Process.  Priority is a value between 0-5 where
        2 is normal priority.  Default sets the priority of the current
        python process but can take any valid process ID. """

    import win32api,win32process,win32con

    priorityclasses = [win32process.IDLE_PRIORITY_CLASS,
                       win32process.BELOW_NORMAL_PRIORITY_CLASS,
                       win32process.NORMAL_PRIORITY_CLASS,
                       win32process.ABOVE_NORMAL_PRIORITY_CLASS,
                       win32process.HIGH_PRIORITY_CLASS,
                       win32process.REALTIME_PRIORITY_CLASS]
    if pid == None:
        pid = win32api.GetCurrentProcessId()
    handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, True, pid)
    win32process.SetPriorityClass(handle, priorityclasses[priority])

から: http://code.activestate.com/recipes/496767/

于 2009-04-24T02:30:45.393 に答える
1

cron ジョブを使用して 1 分おきにスクリプトを実行しないのはなぜですか? 少なくとも、バックグラウンドで継続的に実行される独自のループに依存していません。

于 2009-04-23T14:12:58.177 に答える
0

これは、処理するものが何もない場合でも、CPU に打撃を与える可能性があります。

編集:実際sleep()には引数をミリ秒ではなく秒数として受け取るので、CPUが問題になるとは思いません。それでも、おそらく cron ジョブを使用して、このようなスケジュールを設定できます。

于 2009-04-23T14:10:24.720 に答える
0

CPU に負荷をかけるコストの他に、morejobs()呼び出しのコストがあります。sleep()により高い値を使用することで軽減できます。または、リクエストを受信して​​からzipfile()操作を開始する何らかのメールボックスを使用できます。

一部の操作では、何かを一時的にチェックするバックグラウンド スレッドがスケジュールされているのが普通です。この場合、 sleep()に適切な値を使用するのが最善です。

于 2009-04-23T14:13:41.870 に答える
0

「1000の合理的な意見は、1回の測定に値する」.

やってみなよ。

于 2009-04-23T22:50:54.783 に答える