0

私のコードでは、次のような関数があります。

def myfunc():
    # Don't do anything if there's an instance already
    if get_var('running') == 'true':
         return

    set_var('running', 'true')
    # In case things go wrong
    atexit.register(set_var, 'running', 'false')

    do_something()
    do_something_else()

    set_var('running', 'false')
    # Unregister handler because nothing bad happened
    atexit.unregister(set_var)

set_varデータベースに含まれる変数を設定します。

これらすべての の目的はset_var、複数のインスタンスが同時に実行されるのを防ぐことです。

atexitハンドラーは、プログラムが中断されている場合は正常に機能しますCtrl-Cが、システムなどによって強制終了された場合は機能しません。

私は知ってsignalいますが、ハンドラーをキャンセルすることはできません。

それ、どうやったら出来るの?または、同じ機能を実現するために構造をどのように変更できますか?

4

1 に答える 1

1

私はそれを理解したと思います。

# Used to check if myfunc is running in current program
running_here = False

# Set 'running' variable inside database to 'false' if myfunc was running
# inside current program at the time of exiting or don't do anything otherwise
atexit.register(lambda: set_var('running', 'false') if running_here else None)
# Call atexit handler when SIGTERM is recieved by calling sys.exit
signal.signal(signal.SIGTERM, lambda x, frame: sys.exit(0))

def myfunc():
    global running_here

    # Don't do anything if there's an instance already
    if get_var('running') == 'true':
         return

    # Don't let multiple instances to run at the same time
    set_var('running', 'true')
    running_here = True

    do_something()
    do_something_else()

    # Allow other instances to run
    set_var('running', 'false')
    running_here = False

私がする必要があったのは、何度も何度もキャンセルする必要のないハンドラーを作成することだけでした。グローバル変数を追加することでそれを行いましたrunning_here

プログラムが終了すると、ハンドラーはチェックによって現在のプログラムで関数が実行されているかどうかを確認し、実行されているrunning_here場合、ハンドラーはデータベース内のTrue変数を設定して、他のインスタンスが開始しないようにします。実行されていないことを意味し、変数をリセットする必要がないため、終了するだけです。running 'false'running_hereFalsemyfuncrunning

于 2015-01-28T14:15:56.253 に答える