2011-02-07 22 views
4

私は "私はそれを理解したい"という質問があります。 まず、私はUbuntuでPython 2.6.5を使用しています。pythonスレッドとソケット

Pythonの(スレッドモジュール経由で)スレッドは「スレッド」のみであり、特定の時間内に各スレッドからのコードブロックを実行するようにGILに指示します。実際には実際のスレッドではありません。

したがって、私は1つのスレッドにブロックソケットがあり、今は5秒間データを送信してスレッドをブロックしています。私はスレッドをブロックしている1つのCコマンド(sock.send)であるため、すべてのプログラムをブロックすると予想しました。しかし、私は、メインスレッドが引き続き実行されていることに驚いていました。 問題は、GILがsendのようなブロックコマンドに達した後に、残りのコードをどのように継続して実行できるかです。ここで本当のスレッドを使う必要はありませんか?

ありがとうございました。

答えて

11

Pythonは「実」スレッド、つまり基本となるプラットフォームのスレッドを使用します。 Linuxでは、pthreadライブラリ(興味があればhere is the implementation)を使用します。

Pythonのスレッドに関して特別なのはGILです。このグローバルロックを保持しているスレッドは、Pythonのデータ構造のみを変更できます。したがって、多くのPython演算では複数のプロセッサコアを使用することはできません。しかし、ブロッキングソケットを持つスレッドはGILを保持しないため、他のスレッドには影響しません。

GILは誤解されることが多く、Pythonではスレッドがほとんど役に立たないと人々は考えています。 GILが防ぐ唯一のことは、複数のプロセッサコアで「純粋な」Pythonコードを同時に実行することです。 I/Oのブロック中にスレッドを使用してGUIを応答したり、他のコードを実行すると、GILは影響を与えません。スレッドを使用してNumPy/SciPyのようなC拡張モジュールを複数のプロセッサコアで同時に実行すると、GILは影響を与えません。

6

潜在的に遮断またはI/O、画像処理、及びnumpyの数は、などの長時間実行操作を、クランチ

注意、GIL外起こること。言及wiki page on GILパイソン

+0

私はxソケット(または他のi/oオブジェクト)があり、それらのすべてがバックグラウンド(サーバ)で処理されていると、2つの実際のスレッドがあることを意味します:GILとGILの外、ブロックされ、他もブロックされますか? または私は本当のスレッドを持っていますか? (私が「xスレッドを持っている」とは、同じ時間にx個のスレッドがあっても1秒未満であっても) – RoeeK

+0

よく、テストの後に答えがx実際のスレッドだと思います。物事がより明確になりました。 – RoeeK

3

GIL(グローバルインタープリタロック)は単なるロックであり、単独では動作しません。むしろ、Pythonインタプリタは必要に応じてそのロックを取得し、解放します。通常、ロックはPythonコードの実行中に保持されますが、下位レベルの関数(たとえばsock.send)への呼び出しでは解放されます。 Pythonスレッドは実際のOSレベルのスレッドなので、スレッドはPythonコードを並列に実行しませんが、一方のスレッドが長時間実行するC関数を呼び出すと、GILは解放され、最初のスレッドが終了するまで別のPythonコードスレッドが実行されます。