2

30分ごとに同時にcrontabから2つのPythonスクリプトを実行します。例:

00,30 6-19 * * 0-5 /.../x.py site1
*/3 6-19 * * 0-5 /.../y.py site2

最初に、両方のスクリプトは、いくつかのデータをログに出力するモジュールのインポートを行います。

name = os.path.basename(sys.argv[0])
site = sys.argv[1]
pid = os.getpid()

時折(!)2番目のスクリプトyは、スクリプトxのログ入力引数に出力します。name=xおよびsite=site1で出力されるプロセスのPIDは同じではありません。なぜこれが起こっているのですか、どうすればこれを回避できますか?

PS問題は私が使用しているロガーに関連していると思います。スクリプトは、別のスクリプトで作成されたロガーを使用できますか?この場合、最初のスクリプトに関連するデータが各行に出力されます。各スクリプトは同じコードを実行します。

log = logging.getLogger('MyLog')
    log.setLevel(logging.INFO)
    dh = RotatingSqliteHandler(os.path.join(progDirs['log'],'sqlitelog'),processMeta, 5000000)
    log.addHandler(dh)

ロガーハンドラーは次のように定義されます。

class RotatingSqliteHandler(logging.Handler):
   def __init__(self, filename, progData, maxBytes=0):
       logging.Handler.__init__(self)
       self.user = progData['user']
       self.host = progData['host']
       self.progName = progData['name']
       self.site = progData['site']
       self.pid = random.getrandbits(50)
    .....

ログでは、ロガーが最後の行で生成するプロセスIDが両方のスクリプトで同じであることがわかります。

'MyLog'の代わりに、実行する各スクリプトに固有のロガー名を使用してみます。ロガーインスタンスが別のプロセスから取得できるのは奇妙ですが。

4

4 に答える 4

2

2つのスクリプトが「同時に実行される」場合、オペレーティングシステムがプロセスに優先順位を割り当てる方法に応じて、それらが出力する行が混在する可能性があります。

したがって、ログで次のようなものを取得できます。

x.py: /tmp/x.py
…
… # Other processes logging information
…
y.py: /tmp/y.py
x.py: site1  # Not printed by y!!
x.py: PID = 123
…
… # Other processes logging information
…
y.py: site2
y.py: PID = 124

各行の前に各プログラムベース名を付けると、まだ問題が発生しますか?

于 2010-09-19T07:58:47.383 に答える
2

multiprocessingモジュールなどを使用して特別な準備がなされていない限り、あるPythonプロセスが別のPythonプロセスのオブジェクトにアクセスすることはできません。ですから、表面上はどんなに見えても、それが起こっているとは思いません。

これを確認するには、代替ハンドラー(FileHandlerまたはなどRotatingFileHandler)を使用して、問題が引き続き発生するかどうかを確認します。そうでない場合は、RotatingSqliteHandlerロジックを調べる必要があります。

もしそうなら、そして問題を繰り返し示す小さなスタンドアロンスクリプトを思い付くことができるなら、bugs.python.orgに問題を投稿してください。私は確かに調べます。(私はPythonロギングパッケージを維持しています。)

于 2010-09-26T10:37:36.263 に答える
0

これは、次のに何らかの形で関連している可能性がありますか?

getLogger()は、指定された名前のロガーインスタンスへの参照を返します(指定されている場合)。指定されていない場合はrootを返します。名前はピリオドで区切られた階層構造です。同じ名前でgetLogger()を複数回呼び出すと、同じロガーオブジェクトへの参照が返されます。

両方のスクリプトを互いに十分に「接続」して、これが役割を果たすことができるでしょうか。たとえば、y.pyimportx.pyの場合、両方x.pyで同じロガーを取得し、それぞれy.pyを呼び出すと同じロガーを取得logging.getLogger('myLog')します。

于 2010-09-19T20:36:26.453 に答える
0

この質問は私を困惑させます:ここにさらに別のアイデアがあります!ランダムジェネレーターには、「現在のシステム時刻」をシードできます(コンピューターに乱数のソースが存在しない場合)。Python 2.7では、これはへの呼び出しを通じて行われtime.time()ます。重要なのは「すべてのシステムが1秒よりも優れた精度で時間を提供するわけではない」ということです。より一般的には、両方のプロセスで同じであるとが互いに十分に接近して実行さx.pyれることがあり、その結果、両方のプロセスで同じ結果が得られる可能性がありますか?これは、あなたが観察したように、例外的にのみ現れる問題と互換性があります。y.pytime.time() random.getrandbits(50)

マシンの「解像度」はtime.time()どれくらいですか(異なる時間の間の最小間隔)?おそらく、2つのランダムジェネレーターが例外的に同じ方法でシードされるのに十分な大きさです。

于 2010-09-20T20:11:04.767 に答える