1

私は次のようなクラスを持っています:

class A:
    def __init__(self, filename, sources):
        # gather info from file
        # info is updated during lifetime of the object

    def close(self):
        # save info back to file

現在、これはサーバープログラム内にあるため、シグナルによる事前の通知なしにシャットダウンされる可能性があります。可能であれば、クラスがその情報を確実に保存するようにこれを定義するのは安全ですか?

def __del__(self):
    self.close()

そうでない場合は、代わりに解決策として何を提案しますか?

4

4 に答える 4

2

後でまで待つことは、何かを信頼できるものにするための戦略ではありません。実際、あなたは完全に反対の方向に行かなければなりません。永続化する必要があるものを見つけたらすぐに、それを永続化するためのアクションを実行する必要があります。実際、信頼性を高めたい場合は、最初に、変更をコミットしようとしているときに発生する可能性のある障害から回復するために必要な手順をディスクに書き込む必要があります。疑似パイソン:

class A:
    def __init__(self, filename, sources):
        self.recover()
        # gather info from file
        # info is updated during lifetime of the object

    def update_info(self, info):
        # append 'info' to recovery_log
        # recovery_log.flush()
        # write 'info' to file
        # file.flush()
        # append 'info-SUCCESS' to recover_log
        # recovery_log.flush()

    def recover(self):
        # open recovery_log
        # skip to last 'info-SUCCESS'
        # read 'info' from recover_log
        # write 'info' to file
        # file.flush()
        # append 'info-SUCCESS' to recover_log
        # recovery_log.flush()

重要な点は、recover()毎回発生flush()することと、次のステップが発生する前にデータがディスクに確実に出力されるように、すべてのステップの後にが続くことです。もう1つの重要なことは、リカバリログ自体で追加のみが発生することです。ログ内のデータが破損する可能性があるような方法で上書きされるものはありません。

于 2011-06-25T00:57:16.697 に答える
1

いいえ、あなたは決して安全ではありません。

運用システムが事前の通知なしにあなたを殺したい場合、それはそうします。あなたはそれについて何もすることができません。プログラムは、命令の後でいつでも実行を停止でき、追加のコードを実行する機会がありません。

殺害信号からサーバーを保護する方法はありません。

必要に応じて、より少ないシグナルをトラップし、オブジェクトを手動で削除して、への呼び出しを強制することができますclose()

于 2011-06-24T22:36:20.110 に答える
1

整然としたクリーンアップには、 sys.atexitフックを使用できます。closeメソッドを呼び出す関数をそこに登録します。onオブジェクトのデストラクタは、終了時に呼び出されない場合があります。

于 2011-06-24T22:57:33.953 に答える
1

この__del__メソッドは、インタープリターが終了したときにまだ存在しているオブジェクトに対して呼び出されることが保証されていません。

__del__呼び出されても、呼び出すのが遅すぎる可能性があります。特に、呼び出したいモジュールがアンロードされた後に発生する可能性があります。キースが指摘したように、sys.atexitの方がはるかに安全です。

于 2011-06-24T23:07:15.473 に答える