7

Python を埋め込み、Python から C++ へのコールバックを許可し、Pythhon コードがスレッドを生成できるようにし、デッドロックを回避する方法はありますか?

問題はこれです:

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

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

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

問題は、Python を呼び出すときに GIL を保持していても、Python が GIL を放棄し、別のスレッドに渡してから、そのスレッドがホストに呼び出され、ホストのロックを取得することを期待している可能性があることです。一方、ホストはホスト ロックと GIL ロックを取得し、Python を呼び出します。デッドロックが発生します。

ここでの問題は、私が GIL を呼び出している間、Python が GIL を別のスレッドに放棄することです。それが期待されていることですが、ロックをシーケンスすることは不可能です-最初にGILを取得し、次に独自のロックを取得し、次にPythonを呼び出しても、Pythonは別のスレッドからシステムを呼び出し、独自のロックを取得することを期待しています. (GIL を解放することでシーケンスを解除したため)。

システム内で考えられるすべてのロックに GIL を使用するシステムの残りの部分を作成することはできません。Python がそれを別のスレッドに解放する可能性があるため、それは正しく機能しません。

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

それで、これができないのはただの場合ですか?

4

3 に答える 3

2

Python によって呼び出されるコードは、ロックを取得する前に GIL を解放する必要があります。そうすれば、デッドロックに陥ることはないと思います。

于 2009-04-29T21:49:50.637 に答える
2

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

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

独立したプロセス (それぞれに独自のスレッド プールがある) は、管理が容易な場合があります。

于 2009-04-29T18:44:19.803 に答える
-1

最近、pyopenssl リストで同様の問題について議論がありました。これを説明しようとすると間違ってしまうのではないかと心配しているので、代わりに問題の問題を紹介します。

于 2009-04-30T18:53:15.793 に答える