1/4 ページ
スレッド化は非同期コードを実装する最も基本的な方法ですが、Python のスレッド化は GIL によって複雑になります。 私の新しい本からのこの抜粋で、スレッド化の基本を見つけてください プログラマーの Python: 非同期.
スレッドはしばしば軽量プロセスとして説明されますが、スレッドはプロセスによく似ていますが、重要な違いがいくつかあります。 この章では、単一のプロセス内でスレッドを作成および制御する方法を発見します。
multiprocessing モジュールは threading モジュールに基づいているため、この章の多くは前の章と似ていますが、このレベルでも重要な違いがあります。
プログラマーの Python:
非同期
スレッド、プロセス、非同期など
印刷本として入手可能になりました:Amazon
コンテンツ
1) Python のライトニング ツアー
Python の起源、基本的な Python、データ構造、制御構造 – ループ、スペースの問題、条件とインデント、パターン マッチング、すべてがオブジェクト – 参照、関数、オブジェクトとクラス、継承、メインとモジュール、Python の IDE、Pythonic – Theメタ哲学、次の場所、要約。
2) 非同期の説明
シングルスレッド、 プロセス、 I/O バウンドおよび CPU バウンド、スレッド、ロック、デッドロック、複数のスレッドを使用するプロセス、シングル スレッドの非同期、イベント、イベントまたはスレッド、コールバック ヘル、複数の CPU – 同時実行、概要。
3) 処理ベースの並列処理
抽出 1 – プロセス ベースの並列処理
プロセス クラス、デーモン、プロセスの待機、最初のプロセスの完了の待機、Pi の計算、Fork v Spawn、Forkserve、開始方法の制御、概要。
4) スレッド
抽出 1 –-スレッド
スレッド クラス、スレッドと GIL、スレッド ユーティリティ、デーモン スレッド、スレッドの待機、ローカル変数、スレッド ローカル ストレージ、複数のスレッドによる Pi の計算、I/O バウンド スレッド、Sleep(0)、タイマー オブジェクト、概要。
5) ロックとデッドロック
競合状態、ハードウェアの問題または Heisenbug、ロック、ロックとプロセス、デッドロック、コンテキスト管理ロック、再帰ロック、セマフォ、アトミック操作、アトミック CPython、ロックフリー コード、ロックを使用した Pi の計算、概要。
6) 同期
結合、最初から最後まで、イベント、バリア、条件オブジェクト、普遍的な条件オブジェクト、概要。
7) データの共有
キュー、パイプ、スレッドのキュー、共有メモリ、共有 ctypes、Raw 共有メモリ、共有メモリ、マネージャー、コンピューティング Pi 、概要。
8) プロセスプール
プール プロセスの待機、AsyncResult を使用した Pi の計算、Map_async、Starmap_async、即時結果 – imap、MapReduce、共有とロック、概要。
9) プロセスマネージャー
SyncManager、プロキシの仕組み、ロック、マネージャーを使用した Pi の計算、カスタム マネージャー、カスタム データ タイプ、BaseProxy、プロパティ プロキシ、リモート マネージャー、リモート プロシージャ コール、最終的な考え、まとめ。
10) サブプロセス
プログラムの実行、入力/出力、Popen、相互作用、ノンブロッキング読み取りパイプ、サブプロセスの使用、概要。
11) 先物
Futures、Executors、I/O-Bound の例、Future の待機、Future Done コールバック、例外の処理、データのロックと共有、パラメーターのロックとプロセス、初期化子を使用した共有グローバルの作成、プロセス マネージャーを使用したリソースの共有、Future の共有およびデッドロック、先物、プロセス プールまたは同時先物を使用した Pi の計算、概要。
12) 基本非同期
抽出 1 基本非同期
コールバック、Future と Await、コルーチン、Await、Awaiting Sleep、タスク、実行順序、タスクと Future、コルーチンの待機、シーケンシャルとコンカレント、タスクのキャンセル、例外の処理、共有変数とロック、コンテキスト変数、キュー、概要。
13) asyncio の使用
抽出 1 Asyncio Web クライアント
ストリーム、Web ページのダウンロード、サーバー、Web サーバー、SSL サーバー、ストリームの使用、ブロッキングからノンブロッキングへの変換、スレッドでの実行、スレッドを使用しない理由、CPU バウンド タスク、非同期ベースのモジュール、他のイベントの操作ループ – Tkinter、サブプロセス、概要。
14) 低レベル API
抽出 1 – ストリームと Web クライアント
イベント ループ、ループの使用、プロセスでのタスクの実行、asyncio を使用した Pi の計算、ネットワーク関数、
トランスポートとプロトコル、UDP サーバー、UDP クライアント、ブロードキャスト UDP、ソケット、イベント ループの実装、適切な非同期操作の条件、概要。
付録 I Visual Studio Code での Python
スレッドクラス
Python プログラムの実行を開始すると、通常はメイン スレッドと呼ばれる 1 つのスレッドができます。 これは、Python インタープリターを実行するだけで、Python プログラムを実行します。 Thread クラスを使用して、追加のスレッドを作成できます。
class threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)
ここで、group は使用されません。target は、スレッドの実行を開始するための callable を指定します。name は、スレッドのオプションの識別子であり、args と kwargs は、ターゲットに渡される位置引数とキーワード引数です。 デーモン パラメーターの説明は、後で行うのが最善です。
Thread オブジェクトを取得したら、start メソッドを使用して新しいスレッドで実行中の callable を開始できます。
import threading def myThread(): print("Hello Thread World")
t1=threading.Thread(target=myThread) t1.start()
プログラムが終了する前に、新しいスレッドによって Hello Thread World が表示されます。 ターゲットを実行するスレッドはメイン スレッドと同じプロセスにあり、メイン スレッドがアクセスできるすべてのグローバル変数にアクセスできます。両方のスレッドが同じメモリ空間を共有します。 これにはいくつかの重要な結果があり、後で詳しく説明します。
スレッドの name 属性は、純粋にスレッドを識別するために使用するためのものであり、システムにとっては重要ではありません。 ident と native_id の 2 つの属性は、スレッドの実行時にシステム全体で一意であるため、より便利です。 ident 属性は、システムによって割り当てられる整数です。 これはスレッドのシステム識別子であり、スレッド ID を必要とする他のシステム コールで使用できます。 どちらもシステム全体でグローバルに一意ですが、スレッドの実行中のみです。 スレッドが終了すると、割り当てられた ident と thread_id が再利用される場合があります。 native_id はすべてのシステムで使用できるわけではなく、Python 3.8 以降でのみ使用できることに注意してください。
スレッドと GIL
スレッドは、ランタイム環境を共有するという点でプロセスとは大きく異なります。 つまり、同じプロセス内で実行されるため、同じ変数とオブジェクトのセットにアクセスできます。 一方、プロセスはそれぞれ、プログラム内のすべての変数の独自のコピーを持ち、それらの間に相互作用はありません。 このようにリソースを共有すると物事が単純になるように見えますが、多くの点で別の問題が生じます。
これを書いている時点で、もう 1 つの主要な問題は GIL (Global Interpreter Lock) です。 CPython の現在の実装、および PyPy などの他の実装では、一度に 1 つのスレッドのみが Python インタープリター コードを使用できます。 これは、CPU またはコアが 1 つしかないシステムでは、一度に 1 つのスレッドしかアクティブにならないため、あまり重要ではありませんが、マルチコア マシンでのプログラムの実行速度が低下します。
Python の他の実装 (Jython など) は GIL を使用しませんが、実際には CPython よりも遅いか、CPython が行うすべてのモジュールのサポートが不足している可能性があります。 CPython から GIL を削除する試みと、そのパフォーマンスを改善する試みの両方があります。 GIL が存続している主な理由は、Python がスレッドセーフではない C ベースのライブラリを使用できるようにし、シングルスレッド プログラムを高速に保つためです。
.