2011-06-24 13 views
1

私はこのシナリオを持っています:Pythonマルチスレッド

Zope/Ploneといくつかの鉱山のpython APIで作成されたWebページ。 Webページがあり、それを "a"と呼びます。これは、Pythonメソッドがデータベース(Postgres)を呼び出し、情報を返します。ページ "a"でデータベースデータを "オフライン"に変更することができます(変更はデータベースに即座に書き込まれるのではなく、「保存」を押してPython APIメソッドを呼び出す2番目の瞬間です)。だから、このシナリオを想像してみましょう。「サム」と呼ばれるユーザーがページを読み込んでデータを修正し始めます。一方、「サラ」と呼ばれるユーザは、「保存」をクリックしてページ「a」によってデータベースを修正する。現在、Samは実際のデータベースデータを持っていません。彼は「保存」を押して、Saraのデータ変更を上書きします。

リアルタイムで私のページにアラートが表示されます。

AJAX呼び出しをブロックすることはできません。ページのレンダリングを続けてください。 AJAXはPythonメソッドを呼び出し、無限ループ( "X"条件)を行うスレッドを作成します。データベースにデータを書き込む際には、「X条件」を変更してスレッドを停止し、AJAXに戻る関数を呼び出します。

また、データベースを変更したいすべてのユーザーに自由にアクセスできるので、データベースをロックできません。

私の問題は、どのように私はPythonスレッドを識別できますか?私は、スレッドから継承するクラスのすべてのメソッドがパラメータとして "self"を求めていることを見てきました。さらに、 "a"ページにアクセスする際にスレッドを呼び出さなければなりません。これはコードのどこかにあります(例えば、 "スレッドモジュール")が、他のモジュールに挿入されています。だから、私のアイデアをどうすれば実現できますか?

そして、誰かが代わりのアイデアを持っている場合、あなたは議論している問題のいずれかの問題もなく私に言う:)

答えて

3

をレルムは、一般的に、「並行処理」と呼ばれています。ターゲットアイテム内のフィールドが変更されたときに、メソッドが更新を警告またはブロックするため、このアプローチは通常「ペシミスティック並行性」と呼ばれます。これを行う1つの方法は、アイテムが選択されたときにどのように見えるかを追跡し、データベースバージョンが選択したバージョンとまったく同じか、特定の時間以降に更新されていない場合にのみ更新することです(タイムスタンプフィールドは役立ちます) )。一方のユーザーが更新したフィールドをチェックし、もう一方のユーザーによって更新されていないデータストアに戻ってチェックするオプティミスティック並行性を試すこともできます。並行処理をサポートするORMライブラリを選択すると、これらの方法はどちらも簡単です。

お気に入りのPython Webライブラリはdjangoです。ここでは、あなたが解決しようとしているのと同じ状況についての質問があります:Django: How can I protect against concurrent modification of database entries。私はそれが助けて欲しい

あなたが提案した方法で並行処理を行うことは可能ですが、ほとんどの状況では避けるべきです。私はこれまで多種の副作用があり、統一されたデータ・アクセスを持たない複雑なオブジェクトを持つ大規模なシステムに並行性を追加するときにこれを行っています(システムの存続期間に約5つのデータ・アクセス方法がありました。バグが発生しやすく、複雑な方法で同時実行性を処理することができます(私は、クライアントアプリケーションを持っていて、オブジェクトのタイプと識別子、それをチェックアウトしたユーザを記述したデータテーブルでアイテムをマークアウトした後にウォッチャースレッドを開始したと思います彼らがチェックアウトしたとき、そしてそれがどれだけ有効であったか、オブジェクトをチェックアウトしたクライアントが終了したときにそれをチェックしなかった場合)。

アイテムに変更が発生したときにORMを使用せずにメッセージを表示する場合は、最後に更新されたタイムスタンプ列をオフにして、AJAXコールをチェックして最後の更新時間アイテムを最初に読み込んだときよりも大きいです。したがって、これを行う一般的な方法をコーディングする場合は、単にテーブル名、プライマリキー、およびタイムスタンプが必要になります。

Webサービスメソッドは次のようになります。ライブラリをマルチスレッドのpythonについては

def is_most_current(table_name, id): 
    db = MySQLdb.connect(passwd="moonpie",db="thangs") 
    c=db.cursor() 
    c.execute("SELECT last_updated from %s where id = %s", (table_name, id)) 
    return c.fetchone() 

、Pythonのスレッドが混乱していると、パフォーマンスの低下をもたらすPythonのグローバルインターロックの問題のおかげで、あなたは実際に新しいプロセスを生成することもできます多くの場合(マルチプロセッシングライブラリはかなり同等であり、並列処理シナリオではより良い性能を発揮します)。あなたが扱っているクラスのインスタンスへの参照のためのPythonコンベンションである限り、これはC言語のような "this"と似ています。スレッドを構築するときに、スレッドに固有の名前を付けることで、スレッドを簡単に識別できます。詳細は、multiprocessingまたはthreadingドキュメントを参照してください。この問題のスレッディングを避けることができれば、そうすることをお勧めします。

+0

あなたの答えは良いですが、特定のアイタントで、 "a"ページを開いたときに別のユーザーがデータベースを更新したことに気づきたいと思います。次に、プロペラの方法でフィールドを変更します( "a"ページで) – DonCallisto

+0

私の答えが更新されましたが、あなたのコメントを得たときに最後のいくつかの段落を入力していました。 – marr75

関連する問題