2009-04-29 21 views
7

Pythonを組み込み、PythonからC++へのコールバックを許可し、Pythhonコードでスレッドを生成させ、デッドロックを回避する方法はありますか?スレッドを使ったPython埋め込み - デッドロックの回避?

は問題はこれです:Pythonのに呼び出すには

  • 、私はGILを保持する必要があります。通常、インタープリタを最初に作成したときにメインのスレッド状態を取得し、Pythonにコールする前にPyEval_RestoreThread()を使用してGILを取得し、スレッド状態でスワップすることで、これを行います。

  • 私は、Pythonから呼び出されると、ホストの別のクリティカルセクションで保護されている保護されたリソースにアクセスする必要があるかもしれません。これは、PythonがGILを保持している可能性があることを意味します(私が最初に呼び出されたスレッド以外のスレッドから潜在的に)。そして保護ロックを取得しようとします。

  • Pythonを呼び出すときに、同じロックを保持する必要があるかもしれません。これは、たとえば、オブジェクトのコレクションを繰り返し処理している可能性があるためです。

問題がホストを取ることを期待し、私は、Pythonに呼び出したとき、私はGILを保持していても、Pythonは、それをあきらめ、別のスレッドにそれを与える、その後、私のホストにそのスレッドの呼び出しを持っているかもしれないということですロック。一方、ホストはホストロックとGILロックを取り、Pythonを呼び出します。デッドロックが続く

ここで問題となるのは、Pythonが呼び出されている間にGILを別のスレッドに放棄してしまうことです。それはそれが期待されるものですが、ロックをシーケンスすることが不可能になります。私が最初にGILを取ってから自分のロックを取り、Pythonを呼び出すと、Pythonは自分のロックを取ることを期待して別のスレッド(GILを解放してGILを順序付けしなかったため)。

私のシステムの残りの部分は、システム内のすべての可能なロックに対してGILを使用することはできません。それは、Pythonがそれを別のスレッドにリリースする可能性があるため、正しく動作しません。

私は、ホストのすべてのコードを制御していないため、私のホストがPythonを入力するときにロックを保持しないことを実際に保証することはできません。

これはできないのでしょうか?

+0

ホストロックを取得する前にGILを保持するようにC++コードを要求することはできますか? – Dave

答えて

2

"Pythonを呼び出すときに、同じロックを保持する必要があるかもしれません。オブジェクトのコレクションなどを繰り返し処理している可能性があるからです。

これは、複数のスレッドを持つ単一のプロセスが適切でないことを示すことがよくあります。おそらく、これは、コレクションの特定のオブジェクトを持つ複数のプロセスがより理にかなっている状況です。

それぞれ独自のスレッドプールを持つ独立プロセスは、管理が容易です。

+0

単一のプロセスは私が必要とするものです(問題のプロセスは実際にはWebブラウザのプラグインです)。したがって、残念ながら、あなたの提案は私の質問に答えることはできません。 –

+1

あなたの質問を追加の事実で更新してください - コメントに情報を追加しないでください。 「Webブラウザプラグイン」は新しい情報であり、質問に属します。 –

2

pythonによって呼び出されるコードは、ロックを取る前にGILを解放する必要があります。 そのように私はそれがデッドロックに入ることはできないと信じています。

+0

GILは、Pythonインタプリタの内部データ構造を保護するためだけに存在することを忘れないでください。スレッドがPython以外のコードを呼び出すと、そのコードが実行されている間に安全にGILを解放することができます。 – mhsmith

-1

最近、pyopensslのリストに同様の問題についての議論がありました。これを説明しようとするとうまくいけば間違ってしまうので、代わりにthe problem in questionに紹介しましょう。

関連する問題