毎分cron、単一のインスタンスのみを保証


9

スクリプトを毎分(または2または5など)実行する方法はありますが、まだ実行されていない場合に限られますか?

毎分実行する必要があるスクリプトのセットがあります。場合によっては、1秒で開始および終了することもあれば、5分間続くこともあります。

同時実行を回避する現在の方法はis_running、各スクリプトにフラグを設定し、それがまだ有効になっている場合は終了することです。ただし、これは少し信頼できません(つまり、致命的なエラーが発生すると、スクリプトが停止した後でもフラグが有効のままになります)。

独自の小さなマネージャーを作成することもできますが、もっとファッショナブルなソリューションがすでに存在するかどうか疑問に思っています。


+1私もこれに興味があります。答えはわかりませんが、可能な解決策に興味があります。
Saif Bechan 2010

微妙なcronは多くの "make me a daemon"を
嗅ぎ

回答:


8

より良い方法はflock、pidfileの代わりに使用することです。マンページを確認してください:flock(1)。利点は、プロセスがどのように終了/終了しても、ロックがプロセスとともに失われることです。


3

私はワーナーのpidファイルの回答に同意する傾向があります。ただし、Anacronの次の機能はこれを実現しますか?

-s
    Serialize execution of jobs. Anacron will not start a new job before the previous one finished. 

私はそれを自分でテストしていません。anacronのドキュメントが十分に見つかりません...

特に怠惰にしたい場合は;-) ps出力を調べてプロセスが実行中として返された場合は、スクリプトを終了させることができます。ただし、lock / pidファイルが最適です。


anacronはcronのより新しいバージョンであるため、古い標準よりも多くの機能を備えています。「方法」については、おそらく子プロセスが停止したときにトリガーされるSIGCHLDハンドラーを登録します。したがって、実行中の子を追跡し、それらのジョブを単にスキップできます。
ハビエル

@ハビエル:私は「anacronはcronのより新しいバージョンなので、古い標準よりも多くの機能を備えています」には同意しません。何anacroncronするかといくつかの重複がありますが、それらは異なる問題を解決します。を使用してcron、マシンがダウンしたために失われたジョブをどのように開始しますか?を使用してanacron、12月25日または5分ごとにどのようにジョブを開始しますか?(もちろん、スクリプトによる回避策は可能ですが、それは私が話していることではありません。)
通知があるまで一時停止します。

@Kyle:このオプションにより、同時に実行するようにスケジュールされたさまざまなジョブが一度に1つずつ実行されます。これはOPのニーズに応じて機能する可能性がありますが、他のジョブをブロックするか、他のジョブがそれをブロックします。また、anacron1日より短い期間は実行されません。
追って通知があるまで一時停止。

@Dennis Williamson:私はあなたが正しいと思います、私は歴史の詳細をチェックしていません。しかし、それでも、cronがかなり確立された後にanacronプロジェクトが開始され、それに触発されていることに同意するでしょう。したがって、cronにはない機能があることは驚くに値しません。また、元の質問はcronに関するものでした
Javier

1

それがそのアプローチの適切なソリューションです。通常、pidファイルが使用され、pidテストがプロセスに対して実行され、プロセスが実行されていることを確認します。古い場合、ロックファイルが削除され、プロセスはとにかく実行されます。

追加のインテリジェンスは通常、cronで実行するのではなく、デーモンとしてソフトウェア自体に書き込まれます。


1

スクリプトがflock(2)syscallをサポートする言語でコーディングされている場合は、関数呼び出しでもロックファイルをflock()できます。例:

これをサポートしていないBashまたは他のスクリプト言語に悩まされている場合は、flock(1)ですでに提案されている解決策も問題ありません。

PSいずれの場合も、別のロックファイルを1回だけ作成し(まだ存在しない場合)、削除しないでください。ディレクトリ「/ var / lock」は、このようなファイルに適した場所です。


0

これは、スクリプトがpythonで実行される場合の解決策です(または、次のコマンドの前に実行するpythonコマンドを作成できます)-先週、この正確な問題に遭遇し、いくつかの良い解決策を見つけましたが、非常にシンプルでクリーンなpythonパッケージをPyPIにアップロードしました。ロック__file__するためにカスタムリソース名を付けることを考える必要がないようにロックすることもできます。

インストール: pip install quicklock

それを使用することは非常に簡単です:

[nate@Nates-MacBook-Pro-3 ~/live] python
Python 2.7.6 (default, Sep  9 2014, 15:04:36)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from quicklock import singleton
>>> # Let's create a lock so that only one instance of a script will run
...
>>> singleton('hello world')
>>>
>>> # Let's try to do that again, this should fail
...
>>> singleton('hello world')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/nate/live/gallery/env/lib/python2.7/site-packages/quicklock/quicklock.py", line 47, in singleton
    raise RuntimeError('Resource <{}> is currently locked by <Process {}: "{}">'.format(resource, other_process.pid, other_process.name()))
RuntimeError: Resource <hello world> is currently locked by <Process 24801: "python">
>>>
>>> # But if we quit this process, we release the lock automatically
...
>>> ^D
[nate@Nates-MacBook-Pro-3 ~/live] python
Python 2.7.6 (default, Sep  9 2014, 15:04:36)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from quicklock import singleton
>>> singleton('hello world')
>>>
>>> # No exception was thrown, we own 'hello world'!

見てください:https : //pypi.python.org/pypi/quicklock

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.