実際、Python マルチスレッドに関するもう 1 つの非常に重要なトピックは、
GIL(
Globalインタープリター ロック、グローバル インタープリター ロック)。
''' @Author: Runsen @微信公众号: Python之王 @博客: https://blog.csdn.net/weixin_44510615 @Date: 2020/6/4 '''import threading, timedef my_counter(): i = 0 for _ in range(100000000): i = i+1 return Truedef main1(): start_time = time.time() for tid in range(2): t = threading.Thread(target=my_counter) t.start() t.join() # 第一次循环的时候join方法引起主线程阻塞,但第二个线程并没有启动,所以两个线程是顺序执行的 print("单线程顺序执行total_time: {}".format(time.time() - start_time))def main2(): thread_ary = {} start_time = time.time() for tid in range(2): t = threading.Thread(target=my_counter) t.start() thread_ary[tid] = t for i in range(2): thread_ary[i].join() # 两个线程均已启动,所以两个线程是并发的 print("多线程执行total_time: {}".format(time.time() - start_time))if __name__ == "__main__": main1() main2()复制代码
单线程顺序执行total_time: 17.754502773284912多线程执行total_time: 20.01178550720215复制代码
Pthread (フルネームは
POSIX Thread) ですが、Windows システムでは、それは
Pthread
Windows Thread
GIL の概念は簡単な文で説明できます。つまり、いつでも、スレッドの数に関係なく、単一のCPython インタープリターは 1 バイトのコード
のみを実行できます。この定義に関する注意点:最初に明確にする必要があるのは、GIL は Python
の機能ではなく、Python パーサー (CPython) を実装するときに導入された概念であるということです。 )。 C は一連の言語 (文法) 標準ですが、さまざまなコンパイラを使用して実行可能コードにコンパイルできます。 GCC、INTEL C、Visual C などの有名なコンパイラ同様のことが Python にも当てはまり、CPython、PyPy、Psyco などの異なる Python 実行環境を通じて同じコードを実行できます。他の Python インタープリターには GIL
がない可能性があります。たとえば、Jython (JVM) と IronPython (CLR) には GIL がありませんが、CPython と PyPy には GIL があります。これは、CPython がほとんどの環境でデフォルトの Python 実行環境であるためです。したがって、多くの人の概念では、CPython は Python であり、GIL は Python 言語の欠陥であると当然のことと考えています。ここで明確にしておきます: GIL は Python の機能ではありません。Python は GIL にまったく依存する必要はありません
GIL の本質は、ミューテックス ロックはミューテックス ロックであるため、すべてのミューテックス ロックの本質は同じであり、同時操作を直列操作に変換することで、共有データを同時に 1 つのタスクによってのみ変更できるように制御します。これにより、データのセキュリティが確保されます。
確かなことは、さまざまなデータのセキュリティを保護するには、さまざまなロックを追加する必要があるということです。
GIL の仕組み: たとえば、下の図は、Python プログラムで GIL がどのように動作するかを示した例です。このうち、スレッド 1、2、3 が順番に実行され、各スレッドが実行を開始すると、他のスレッドが実行されないように GIL をロックし、同様に、各スレッドが一定期間実行を終了すると、GIL を解放します。他のスレッドの実行を許可する スレッドはリソースの利用を開始します。
コンピューティング集約型タスクは、大量の計算が必要であり、CPU リソースを消費するという特徴があります。
まず、計算を多用する単純な例を見てみましょう:
''' @Author: Runsen @微信公众号: Python之王 @博客: https://blog.csdn.net/weixin_44510615 @Date: 2020/6/4 '''import time COUNT = 50_000_000def count_down(): global COUNT while COUNT > 0: COUNT -= 1s = time.perf_counter() count_down() c = time.perf_counter() - s print('time taken in seconds - >:', c) time taken in seconds - >: 9.2957003复制代码
これは 1 つのスレッドで、時間は 9 秒です。2 つのスレッドを使用して結果を見てみましょう:
''' @Author: Runsen @微信公众号: Python之王 @博客: https://blog.csdn.net/weixin_44510615 @Date: 2020/6/4 '''import timefrom threading import Thread COUNT = 50_000_000def count_down(): global COUNT while COUNT > 0: COUNT -= 1s = time.perf_counter() t1 = Thread(target=count_down) t2 = Thread(target=count_down) t1.start() t2.start() t1.join() t2.join() c = time.perf_counter() - s print('time taken in seconds - >:', c) time taken in seconds - >: 17.110625复制代码
プログラムの主な動作は計算です。CPU は待機しません。マルチスレッドに変更した後、スレッドを追加した後、スレッド間の頻繁な切り替えにより時間のオーバーヘッドが増加します。当然、時間は増加します。
IO 集中型の別のタイプがあります。ネットワークおよびディスク IO を伴うタスクはすべて IO 集中型タスクです。このタイプのタスクの特徴は、CPU 消費量が非常に少なく、タスクのほとんどが実行されることです。 IO の待機時間が経過し、操作が完了します (IO の速度が CPU やメモリの速度よりもはるかに遅いため)。 IO 集中型のタスクの場合、タスクが多いほど CPU 効率は高くなりますが、制限があります。最も一般的なタスクは、Web アプリケーションなどの IO 集中型のタスクです。
要約: io 集中型の作業 (Python クローラー) の場合、マルチスレッドによってコードの効率が大幅に向上します。 CPU を大量に使用するコンピューティング (Python データ分析、機械学習、深層学習) の場合、マルチスレッドはシングル スレッドよりも若干効率が劣る可能性があります。したがって、データ分野の効率を向上させるマルチスレッドなどは存在せず、演算能力を向上させる唯一の方法は、CPU を GPU と TPU にアップグレードすることです。
関連する無料学習の推奨事項: Python ビデオ チュートリアル
以上がマルチスレッドがシングルスレッドよりも高速であるというのは本当ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。