88

Python でスレッドがどのように機能するかについて頭を悩ませようとしてきましたが、スレッドがどのように動作するかについての適切な情報を見つけるのは困難です。リンクか何かが欠けているだけかもしれませんが、公式ドキュメントはこの件に関してあまり完全ではないようで、適切な記事を見つけることができませんでした.

私が知る限り、一度に実行できるスレッドは 1 つだけで、アクティブなスレッドは 10 命令ごとに切り替わりますか?

適切な説明はどこにありますか、または提供できますか? また、Python でスレッドを使用しているときに遭遇する一般的な問題に注意してください。

4

7 に答える 7

53

はい、Global Interpreter Lock (GIL) のため、一度に 1 つのスレッドしか実行できません。これに関するいくつかの洞察を含むいくつかのリンクを次に示します。

最後のリンクからの興味深い引用:

それが何を意味するのか説明しましょう。スレッドは同じ仮想マシン内で実行されるため、同じ物理マシン上で実行されます。プロセスは、同じ物理マシンまたは別の物理マシンで実行できます。スレッドを中心にアプリケーションを設計する場合、複数のマシンにアクセスするために何もしていません。したがって、1 台のマシンにあるコアの数に合わせてスケーリングできますが (時間の経過とともにかなりの数になります)、実際に Web スケールに到達するには、とにかく複数のマシンの問題を解決する必要があります。

マルチコアを使用する場合、pyprocessingはプロセス ベースの API を定義して実際の並列化を行います。PEPには、いくつかの興味深いベンチマークも含まれています。

于 2008-08-28T00:19:50.320 に答える
36

Python はかなり簡単にスレッド化できる言語ですが、注意点があります。知っておくべき最大のことは、Global Interpreter Lock です。これにより、1 つのスレッドのみがインタープリターにアクセスできます。これは 2 つのことを意味します。1) Python で lock ステートメントを使用することはめったにありません。2) マルチプロセッサ システムを利用したい場合は、別のプロセスを使用する必要があります。EDIT:GILも回避したい場合は、コードの一部をC / C ++に入れることができることも指摘する必要があります。

したがって、スレッドを使用する理由を再検討する必要があります。デュアルコア アーキテクチャを利用するためにアプリを並列化する場合は、アプリを複数のプロセスに分割することを検討する必要があります。

応答性を向上させたい場合は、スレッドの使用を検討する必要があります。ただし、他にもマイクロスレッディングという代替手段があります。検討すべきフレームワークもいくつかあります。

于 2008-08-28T00:00:18.167 に答える
21

以下は、基本的なスレッドのサンプルです。20 個のスレッドが生成されます。各スレッドはそのスレッド番号を出力します。それを実行して、印刷される順序を観察します。

import threading
class Foo (threading.Thread):
    def __init__(self,x):
        self.__x = x
        threading.Thread.__init__(self)
    def run (self):
          print str(self.__x)

for x in xrange(20):
    Foo(x).start()

あなたがほのめかしたように、Pythonスレッドはタイムスライスによって実装されています。これが、「パラレル」効果を得る方法です。

私の例では、私の Foo クラスはスレッドを拡張runし、スレッドで実行したいコードが入るメソッドを実装します。start()メソッドを自動的に呼び出すスレッドオブジェクトで呼び出すスレッドを開始するにはrun...

もちろん、これはあくまでも基本です。最終的には、スレッド同期とメッセージ パッシングのためのセマフォ、ミューテックス、およびロックについて学びたいと思うでしょう。

于 2008-08-27T23:52:59.743 に答える
10

個々のワーカーが I/O バウンド操作を実行している場合は、Python でスレッドを使用します。マシン上の複数のコアにまたがってスケーリングしようとしている場合は、python 用の優れたIPCフレームワークを見つけるか、別の言語を選択してください。

于 2008-08-28T02:34:18.967 に答える
2

GILは、複数のタスクの外観を表示するために、頻繁にポーリングするように設定されていることを覚えておいてください。この設定は微調整できますが、スレッドが実行している作業が必要であるか、多くのコンテキストスイッチが問題を引き起こす可能性があることを提案します。

私は、プロセッサ上に複数の親を提案し、同じコア上で同じような仕事を続けようとするところまで行きます。

于 2009-07-28T22:40:05.843 に答える