4

私のdjangoアプリは、djangoモデルをリモートデータベースに保存します。保存がバーストする場合があります。アプリケーションのメインスレッド(* thread_A *)を、複数のオブジェクトをデータベースに保存する時間から解放するために、* thread_B *を使用してモデルオブジェクトを別のスレッド(* thread_B *)に転送し、保存することを考えましたcollections.deque。それらを順番に。

しかし、私はこの計画についてはよくわかりません。save()新しいデータベースエントリのIDを返すため、データベースが応答した後、つまりトランザクションの最後にのみ「終了」します。

django.db.models.Model.save()本当にGILをブロックし、トランザクション中に他のPythonスレッドを解放しますか?

4

3 に答える 3

7

Djangosave()は GIL に対して特別なことは何もしません。実際、Python コードで GIL を使用してできることはほとんどありません。実行時に、スレッドは GIL を保持する必要があります。

で GIL をリリースするには、次の 2 つの方法しかありませんsave()

  • Python はスレッドの切り替えを決定します (sys.getcheckinterval()指示の後)
  • Django は、GIL を解放するために実装されたデータベース インターフェイス ルーチンを呼び出します。

2 番目のポイントは、探しているものである可能性があります。SQLCOMMITが実行され、その実行中に SQL バックエンドが GIL を解放します。ただし、これは SQL インターフェースに依存するため、一般的なもので実際に GIL* がリリースされているかどうかはわかりません。

さらに、いくつかのステートメントと;save()を実行するだけではありません。GILを保持する必要があるPythonで多くの簿記を行います。要約すると、別のスレッドに移動することで何かが得られるかどうかはわかりません。UPDATE/INSERTCOMMITsave()


更新sqlite: ソースを見て、モジュールとdoの両方がデータベース ルーチンを呼び出しているときに GIL を解放することを知りましたpsycopg。他のインターフェイスも同じことをしていると思います。

于 2012-05-17T07:55:13.400 に答える
3

通常、Django アプリケーションのスレッドについて心配する必要はありません。Apache、gunicorn、または開発サーバー以外のほぼすべてのサーバーでアプリケーションを提供している場合、サーバーは複数のプロセスを生成し、GIL を完全に回避します。例外は、gunicorn を gevent で使用している場合です。この場合、複数のプロセスが存在するだけでなく、それらのプロセス内にマイクロスレッドも存在します。この場合、同時実行性は少し役立ちますが、スレッドを自分で管理して利用する必要はありません。その。GIL について心配する必要がある唯一のケースは、単一のリクエストを処理するために複数のスレッドを生成しようとしている場合です。これは通常は良い考えではありません。

Django の save() メソッドは GIL 自体を解放しませんが、データベース バックエンドは解放します (ほとんどの場合、save() に費やされる時間の大部分はデータベース I/O に費やされます)。ただし、適切に設計された Web アプリケーションでこれを適切に利用することはほとんど不可能です。ビューからの応答は、同期的に行われた場合でも高速である必要があります。処理が多すぎて高速に処理できない場合は、Celery または別のタスクマスターで遅延ジョブを使用して余分な作業を完了してください。ビューでスレッド化しようとすると、クライアントに応答を送信する前にそのスレッドを終了する必要があります。ほとんどの場合、これは何の役にも立たず、余分なオーバーヘッドが追加されるだけです。

于 2012-05-17T16:37:51.893 に答える
-4

Python はそれ自体で何もロックしないと思いますが、データベースはロックします。

于 2012-05-17T07:17:14.517 に答える