18

私が取り組んでいる現在の Python アプリケーションでは、1000 以上のスレッド (Python のスレッド化モジュール) を利用する必要があります。シングル スレッドが最大 CPU サイクルで動作しているわけではありません。これは、私が作成している Web サーバー負荷テスト アプリにすぎません。IE は 200 の Firefox クライアントをエミュレートし、それらすべてが Web サーバーにアクセスし、小さな Web コンポーネントをダウンロードします。基本的には、マイクロ秒ではなく秒単位で動作する人間をエミュレートします。

それで、「Linux / Windowsでpythonがサポートするスレッドの数など」などのさまざまなトピックを読んでいたところ、さまざまな回答がたくさん見られました。スレッドの場合は 8Meg です。これを超えると、カーネルによってスレッドが強制終了されます。

ある人は、これは CPython にとって問題ではないと述べました。これは、一度に 1 つのスレッドしか実行されないため (GIL のため)、膨大な数のスレッドを指定できるからです。これについての実際の真実は何ですか?

4

2 に答える 2

15
  1. 「GILのため、一度に1つのスレッドが実行されています。」まあ、ある種。GILは、一度に1つのスレッドのみがPythonコードを実行できることを意味します。ただし、任意の数のスレッドがIO、その他のさまざまなシステムコール、またはGILを保持しないその他のコードを実行している可能性があります。

    スレッドは主にネットワークI/Oを実行しているようで、任意の数のスレッドが同時にI/Oを実行できます。GILの競争は1000スレッドでかなり激しいかもしれませんが、いつでも複数のPythonプロセスを作成し、それらの間でI / Oスレッドを分割することができます(つまり、fork開始する前に数回)。

  2. 「Linuxカーネルはデフォルトでスレッド用に8Megしか取っていません。」どこで聞いたのかわかりません。たぶん、実際に聞いたのは「Linuxでは、デフォルトのスタックサイズは多くの場合8 MiBです」ということでしたが、これは事実です。各スレッドは、スタック用に8 MiBのアドレス空間(64ビットでは問題ありません)に加えて、追加のメモリマップとスレッドプロセス自体用のカーネルリソースを使用します。ライブラリ関数を使用してスタックサイズを変更できますthreading.stack_size。これは、ディープコールを行わないスレッドが多数ある場合に役立ちます。

    >>> import threading
    >>> threading.stack_size()
    0 # platform default, probably 8 MiB
    >>> threading.stack_size(64*1024) # 64 KiB stack size for future threads
    
  3. このスレッドの他の人は、非同期/非ブロッキングフレームワークの使用を提案しています。まあ、あなたはそれを行うことができます。ただし、最新のLinuxカーネルでは、マルチスレッドモデルは非同期(//)I/O多重化技術と競合selectpollますepoll。非同期モデルを使用するようにコードを書き直すのは簡単なことではないので、スレッドモデルから必要なパフォーマンスを得ることができなかった場合にのみそれを行います。スレッドが実際に人間の待ち時間をシミュレートしようとしている場合(たとえば、ほとんどの時間を睡眠に費やしている場合)、非同期アプローチが実際に遅いシナリオがたくさんあります。これがPythonに当てはまるかどうかはわかりません。Pythonでは、GILの競合を減らすだけで切り替えに値する可能性があります。

于 2012-04-27T04:08:22.837 に答える
3

それらの両方は部分的に真実です:

  • 各スレッドにはスタックがあり、十分な数のスレッドを作成すると、スタックのアドレス空間が不足する可能性があります。

  • PythonにはGILと呼ばれるものもあり、一度に1つのPythonスレッドしか実行できません。ただし、PythonコードがCコードを呼び出すと、別のPythonスレッドの実行中にそのCコードを実行できます。ただし、Pythonのスレッドは依然として物理的であり、スタックスペースの制限があります。

多くのスレッドを使用するのではなく、多くの接続を計画している場合は、非同期設計の使用を検討してください。ツイストはおそらくここでうまくいくでしょう。

于 2012-04-27T04:08:30.007 に答える