学習目標
1. マルチタスクの概念を理解する
2. プロセスの概念とマルチプロセスの役割を理解する
3. マルチプロセスの動作原理とケースライティングをマスターして、マルチタスクを完了する
4. プロセス番号の取得方法とプロセス利用時の注意点をマスターする
5. スレッドの概念とマルチスレッドの役割を理解する
6. マルチプロセスの動作原理とケースライティングをマスターして、マルチタスクを完了する
1. マルチタスクの概念
1.栗を一つ取ります
考えてみます: ネットワーク ディスクを使用してデータをダウンロードするとき、なぜ複数のタスクを同時にダウンロードする必要があるのでしょうか? A: 複数のタスクを同時に実行すると、プログラムの実行効率が大幅に向上します。
2. 質問する
質問: これまでに学んだテクニックを使用して、マルチタスクを実行できますか? 回答: いいえ、以前に作成したプログラムはすべてシングルタスクであるため、つまり、1 つの関数またはメソッドが実行される前に、別の関数またはメソッドが実行されるためです。複数のタスクを同時に実装するには、マルチタスクを使用する必要があります。マルチタスクの最大の利点は、CPU リソースを最大限に活用し、プログラムの実行効率を向上させることです。
3. マルチタスクとは何ですか
マルチタスクとは、複数のタスクを同時に実行することを指します。例: コンピュータにインストールされているオペレーティング システムはすべてマルチタスク オペレーティング システムであり、複数のソフトウェアを同時に実行できます。
4. マルチタスクの 2 つの現れ
①並行 ②並行
5. 同時動作
同時実行性: 一定期間にわたって複数のタスクを交互に実行します。例: マルチタスクを処理するシングルコア CPU の場合、オペレーティング システムは各タスクを交互に実行することを許可します。たとえば、ソフトウェア 1 は 0.01 秒間実行し、ソフトウェア 2 に切り替え、ソフトウェア 2 は 0.01 秒間実行し、その後ソフトウェアに切り替えます。 3、0.01秒間実行…このように繰り返し実行が続き、実際には各ソフトが交互に実行されます。ただし、CPU の実行速度が速すぎるため、一見これらのソフトウェアが同時に実行されているように見えますが、シングルコア CPU は複数のタスクを同時に実行していることに注意する必要があります。
6. 並列運転
並列処理: 複数のタスクを、一定期間にわたって真に同時に一緒に実行します。マルチコア CPU がマルチタスクを処理できるように、オペレーティング システムは CPU の各コアに実行タスクを配置し、複数のコアが同時に複数のタスクを同時に実行します。ここで注意すべき点は、マルチコア CPU は複数のタスクを並行して実行し、常に複数のタスクが同時に実行されることです。
2. プロセスの概念
1. プログラムにマルチタスクを実装する方法
Python では、マルチプロセッシングを使用してマルチタスクを実現できます。
2. プロセスの概念
プロセス (プロセス) は、リソース割り当ての最小単位です。リソース割り当てとオペレーティング システムの動作スケジュールの基本単位です。一般的な理解: 実行中のプログラムはプロセスです。例: qq、wechat などの実行。これらはすべて 1 つのプロセスです。
注: プログラムの実行後、少なくとも 1 つのプロセスが存在します。
3. マルチプロセスの役割
☆マルチプロセスは使用しておりません
考え方: この図は非常に単純なプログラムを示しています。hello.py プログラムが実行されると、コードの実行順序に従って、func_b 関数は func_a 関数が実行された後にのみ実行できます。func_a と func_b が実行できる場合、同時に hello.py が実行されることがわかり、プログラムの効率が大幅に向上します。
☆マルチプロセス採用
3、複数のタスクを完了するための複数のプロセス
1. 複数のタスクを完了するための複数のプロセス
① プロセスパッケージをインポート
import multiprocessing
② プロセスクラスを通じてプロセスオブジェクトを作成 Process
object = multiprocessing.Process()
③ タスクを実行するプロセスを開始
Process object.start()
2. プロセス クラスを使用してプロセス オブジェクトを作成します。
プロセス オブジェクト = multiprocessing.Process([グループ [, ターゲット=タスク名[, 名前]]])
パラメータの説明:
パラメータ名 |
説明する |
---|---|
目標 |
実行するターゲットタスクの名前。ここでは関数名(メソッド名)を指します。 |
名前 |
プロセス名。通常は設定する必要はありません |
グループ |
プロセスグループ、現在は「なし」のみ使用可能 |
3. プロセスの作成と起動のコード
音楽を聴きながらコードを入力します。
import multiprocessing
import time
def music():
for i in range(3):
print('听音乐...')
time.sleep(0.2)
defcoding():
for i in range(3):
print('敲代コード...')
time.sleep(0.2)
if __name__ == '__main__':
music_process = multiprocessing.Process(target=music)
coding_process = multiprocessing.Process(target=coding)
music_process.start()
coding_process.start()
操作結果:
音楽を聴いて…
ノック コード…
音楽を聴いて…
ノック コード…
音楽を聴いて…
ノック コード…
以下は、Python マルチプロセッシング モジュールを使用して並列タスクを実装するコードです。コードでは 2 つの関数 music() とcoding() が定義されており、それぞれ音楽を聴くこととコードを入力するという 2 つのタスクを表します。各タスクは 3 回実行され、各実行後に 0.2 秒停止します。
このコードは、multiprocessing.Process() メソッドを通じて 2 つのプロセス music_process とcoding_process を作成し、各プロセスはターゲット パラメーター (対応するタスク music またはcoding) を指定します。
次に、start() メソッドを通じて 2 つのプロセスが開始され、同時に非同期で実行されます。if name == 'main': この行は Python プログラムのエントリ ポイントであり、マルチプロセス環境でプロセスが繰り返し開始されないようにするために使用されます。このコードを実行すると、2 つのプロセスがそれぞれのタスク、つまり「音楽を聴く...」と「コードをノックする...」の出力を並行して実行していることがわかります。
4. プロセスはパラメータを指定してタスクを実行します
プロセス([グループ [, ターゲット [, 名前 [, 引数 [, kwargs]]]]])
パラメータの説明: これは、プロセス オブジェクトを作成し、新しいプロセスを開始するために使用される Python の関数です。そのパラメータには次のものが含まれます。
-
group: プロセス グループを指定します。通常は必要ありません。デフォルトは [なし] です。
-
target: プロセスの開始時に実行される関数を指定します。呼び出し可能なオブジェクトである必要があります。
-
name: 指定されたプロセスの名前。通常は必要ありません。デフォルトは「なし」です。
-
args: ターゲット関数に渡される引数のタプルを指定します。args=(1,2,'アン',)
-
kwargs: ターゲット関数に渡されるキーワード引数の辞書を指定します。kwargs={'名前':'アン','年齢':18}
ケース: args パラメータと kwargs パラメータの使用
import multiprocessing
import time
def music(num):
for i in range(num):
print('听音乐...')
time.sleep(0.2)
defcoding(count):
for i in range(count):
print( '敲代码...')
time.sleep(0.2)
if __name__ == '__main__':
music_process = multiprocessing.Process(target=music, args=(3,))
coding_process = multiprocessing.Process(target=coding, kwargs ={'カウント': 3})
music_process.start()
coding_process.start()
music_process.join()
coding_process.join()
join() メソッドは、すべてのサブプロセスが実行された後にメイン プロセスが確実に終了するように追加されます。そうでない場合、メイン プロセスはサブプロセスが実行される前に終了します。マルチプロセスプログラミングでは、サブプロセスの実行は非同期であり、メインプロセスとサブプロセスが並行して実行されます。サブプロセスの完了を待たずにメインプロセスが終了すると、サブプロセスが停止する可能性があります。強制終了され、プログラム異常やデータ損失等が発生します。
したがって、プログラムの正常な動作を保証するために、サブプロセスの開始後、メインプロセスを終了する前に、サブプロセスの実行が終了するまで join() メソッドを呼び出してください。join() メソッドはメイン プロセスをブロックし、すべてのサブプロセスが実行されるまでメイン プロセスの実行を続行しません。
ケース: 複数のパラメータの受け渡し
import multiprocessing
import time
def music(num, name):
for i in range(num):
print(name)
print('听音乐...')
time.sleep(0.2)
defcoding(count):
for i in range (count):
print('敲代码...')
time.sleep(0.2)
if __name__ == '__main__':
music_process = multiprocessing.Process(target=music, args=(3, '多任务开始'))
coding_process = multiprocessing.Process(target=coding, kwargs={'count': 3})
music_process.start()
coding_process.start()
操作結果:
マルチタスク開始
音楽を聴く...
ノックコード...
マルチタスク開始
音楽を聴く...
ノックコード...
マルチタスク開始
音楽を聴く...
ノックコード...
このコードは、異なるタスクを同時に実行する複数のプロセスの例を実装しています。具体的な実装は以下の通りです。
マルチプロセッシングおよび時間モジュールがインポートされます。
music() とcoding() の 2 つの関数が定義されています。music() 関数は、文字列名と「音楽を聴く...」という文字列を num ループを通じて出力し、0.2 秒間スリープして、「音楽を聴く」タスクをシミュレートします。coding() 関数は、count 回ループして文字列「Type code...」を出力し、0.2 秒間スリープして、「Type code」のタスクをシミュレートします。
プログラムのメイン エントリで 2 つのサブプロセス、music_process とcoding_process を実行します。このうち、music_process プロセスはパラメーター num=3 と name='multitasking start' を渡して music() 関数を呼び出し、coding_process プロセスはパラメーター count=3 を渡してcoding() 関数を呼び出します。
music_process プロセスとcoding_process プロセスを開始します。
これらのプロセスは同時に実行を開始し、music_process プロセスは名前と「音楽を聴く...」の文字列を num 回出力し、coding_process プロセスは「ノック コード...」の文字列を count 回出力します。プログラムは、さまざまなタスクの実行をシミュレートするために、各出力後に 0.2 秒間スリープします。
プロセスの実行が終了すると、プログラムは終了します。
4番目に、プロセス番号を取得します
1. プロセス番号の役割
プログラム内のプロセス数が増加した場合、メインプロセスとサブプロセス、および別のサブプロセスを区別する方法がなければ、効果的なプロセス管理を行うことができません。実際、各プロセスには独自の番号が割り当てられています。管理の都合。
2. 2つのプロセス番号
① 現在のプロセス番号を取得する
getpid()
② 現在のプロセスの親プロセスの ppid を取得 = 親 pid
getppid()
3. 現在のプロセス番号を取得する
import os
def work():
# 現在のプロセスの番号を取得
print('ワークプロセス番号', os.getpid())
# 親プロセスの番号を取得
print('ワーク親プロセス番号', os.getppid( ))
仕事 ()
ケース: 子プロセス番号を取得する
import multiprocessing
import time
import os
def music(num):
print('music>> %d' % os.getpid())
for i in range(num):
print('听音乐...')
time.sleep( 0.2)
defcoding(count):
print('coding>> %d' % os.getpid())
for i in range(count):
print('敲代码...')
time.sleep(0.2)
if __name__ == '__main__':
music_process = multiprocessing.Process(target=music, args=(3, ))
coding_process = multiprocessing.Process(target=coding, kwargs={'count': 3})
music_process.start()
coding_process。始める()
操作結果:
音楽>> 12232
音楽を聴く...
コーディング>> 1868
コードを入力...
音楽を聴く...
コードを入力...
音楽を聴く...
コードを入力...
Pythonのmultiprocessingモジュールを使って複数のプロセスを作成する例です。
まず、music とcoding という 2 つの関数が定義され、それぞれプロセス ID を出力し、for ループと time.sleep ステートメントを使用して時間のかかる操作をシミュレートします。次に、プログラムのメイン プログラムで、multiprocessing.Process を使用して、music_process とcoding_process の 2 つのプロセスを作成します。それぞれ、target パラメータを使用して実行する関数を指定し、args または kwargs パラメータを使用して、実行する関数のパラメータを渡します。実行されました。次に、start メソッドを呼び出して 2 つのプロセスを開始し、それによって 2 つのプロセスで異なるタスクを同時に実行します。
if name == 'main' を使用するのは、サブプロセスが再帰的に作成するサブプロセスによって引き起こされる一連の問題を防ぐためであることに注意してください。これは、Windows システムでは、すべての Python プログラムが自動的に 1 回実行されますが、Linux/MacOS システムでは、それ以外の場合は実行されないためです。 。
ケース: 親プロセスと子プロセスの番号を取得する
import multiprocessing
import time
import os
def music(num):
print('music>> %d' % os.getpid())
print('music主进程>> %d' % os.getppid())
for i in range (num):
print('听音乐...')
time.sleep(0.2)
defcoding(count):
print('coding>> %d' % os.getpid())
print('music主进程>> %d' % os.getppid())
for i in range(count):
print('敲代码...')
time.sleep(0.2)
if __name__ == '__main__':
print('主进程>> % d' % os.getpid())
music_process = multiprocessing.Process(target=music, args=(3, ))
coding_process = multiprocessing.Process(target=coding, kwargs={'count':3})
music_process.start()
coding_process.start()
操作結果:
メイン処理 >> 15080
音楽 >> 10320
音楽 メイン処理 >> 15080
音楽を聴く...
コーディング >> 19220
音楽 メイン処理 >> 15080
ノックコード...
音楽を聴く...
ノックコード...
音楽を聴く...
ノックコード...
このコードは、Python のマルチプロセッシング モジュールを使用して 2 つのプロセスを作成し、音楽を聴くこととコードを書くという 2 つのタスクの同時実行をシミュレートします。
まず、プロセス内で音楽を聴くタスクとコードを書くタスクをそれぞれ実行する 2 つの関数 music() とcoding() が定義されています。この関数では、os.getpid() と os.getppid() を使用して、現在のプロセスと親プロセスの ID を取得します。
コードでは multiprocessing.Process() 関数を使用して 2 つのプロセスを作成します。music_process プロセスは music() 関数を実行し、coding_process プロセスはcoding() 関数を実行します。
最後に、メイン プロセスで .start() メソッドを使用して 2 つのサブプロセスの実行を開始します。実行結果を観察すると、music() 関数とcoding() 関数のタスクが並行して実行されていることがわかります。 2 つのサブプロセス。
5. プロセス申請時の注意事項
1. グローバル変数はプロセス間で共有されません
実際、子プロセスの作成とは、メイン プロセスのリソースをコピーして新しいプロセスを生成することであり、メイン プロセスと子プロセスは互いに独立しています。
場合:
import multiprocessing
my_list = []
def write_data():
for i in range(3):
my_list.append(i)
print('add:', i)
print(my_list)
def read_data():
print('read_data', my_list )
if __name__ == '__main__':
# データを書き込むプロセスを作成します
write_process = multiprocessing.Process(target=write_data)
# データを読み取るプロセスを作成します
read_process = multiprocessing.Process(target=read_data)
# 関連する処理を実行するプロセスを開始しますタスク
write_process.start ()
time.sleep(1)
read_process.start()
原理分析:
3 つのプロセスはそれぞれ、自分のプロセス内でグローバル変数 my_list を操作します。これは他のプロセスのグローバル変数には影響しません。そのため、グローバル変数はプロセス間で共有されませんが、プロセス間でのグローバル変数の名前は同じですが、その操作は次のとおりです。同じプロセス内のグローバル変数ではありません。
知識ポイントの要約: 子プロセスを作成すると、メイン プロセスのリソースがコピーされます。つまり、子プロセスは、双子のようなメイン プロセスのコピーです。プロセス間でグローバル変数が共有されない理由操作が同じではないためです。プロセス内のグローバル変数は同じですが、異なるプロセスのグローバル変数の名前は同じです。
2. メインプロセスと子プロセスの終了シーケンス
コードデモ:
import multiprocessing
import time
# working function
def work():
for i in range(10):
print('Working...')
time.sleep(0.2)
if __name__ == '__main__':
# サブ
プロセス work_process = multiprocessing を作成します。 Process(target=work)
# サブプロセスの開始
work_process.start()
# 1秒遅延
time.sleep(1)
print('メインプロセスは終了しました')
結果:
このコードは、Python のマルチプロセッシング モジュールを使用してサブプロセスを作成および開始し、メイン プロセスで 1 秒の遅延後にメッセージを出力します。具体的な説明は以下の通りです。
-
マルチプロセッシングおよび時間モジュールをインポートします。
-
work という関数を定義します。この関数は、for ループと time.sleep() 関数を使用して、時間のかかる作業をシミュレートします。
-
if name == 'main': ステートメント ブロックで、ターゲット関数が work である work_process という名前の子プロセスを作成します。
-
子プロセスを開始するには、work_process.start() を呼び出します。
-
time.sleep(1) 関数を使用して、メインプロセスを 1 秒遅延させます。
-
メインプロセスの実行が終了したことを示すメッセージを出力します。
子プロセスとメインプロセスは並行して実行されるため、メインプロセスが 1 秒遅れた後も、子プロセスは引き続きワーカー関数のタスクを実行します。したがって、OSのスケジューリングポリシーによっては、出力情報が子プロセスの出力情報より前後する場合があります。
☆ 解決策 1: デーモン プロセスをセットアップする
import multiprocessing
import time
# working function
def work():
for i in range(10):
print('Working...')
time.sleep(0.2)
if __name__ == '__main__':
# サブ
プロセス work_process = multiprocessing を作成します。 Process(target=work)
# ガーディアンメインプロセスをセットアップします。メインプロセスが終了すると、子プロセスは直接破棄され、子プロセス内のコードは実行されなくなります。 work_process.daemon = True # 子プロセスを開始し
ます
。 process
work_process.start()
# 1
秒遅延します sleep(1)
print('メインプロセスは終了しました')
操作結果:
作業中...
作業中...
作業中...
作業中...
作業中...
メインプロセスが終了しました
このコードは、Python のマルチプロセッシング モジュールを使用してサブプロセスを作成し、その中で作業関数を実行します。
まず、作業関数 work() が定義されています。これはループ内で 10 回実行され、毎回「Working...」を出力し、0.2 秒間スリープします。
メイン プログラムでは、最初にサブプロセス work_process が作成され、work 関数がそのターゲット パラメーターとして渡され、サブプロセスが work 関数を実行する必要があることを示します。
次に、work_process のデーモン属性を True に設定します。これは、子プロセスがデーモン プロセスであることを示します。つまり、メイン プロセスが終了すると、子プロセスも終了し、子プロセス内のコードは実行されなくなります。
次に、子プロセス work_process を開始すると、子プロセスは work 関数内のコードの実行を開始します。メインプロセスは 1 秒遅延した後、「メインプロセスが実行されました」を出力して終了します。
子プロセスはデーモンプロセスであるため、メインプロセスが終了すると子プロセスも破棄され、ワーク関数内のコードは実行されなくなります。
☆ 解決策 2: 子プロセスを破棄する
import multiprocessing
import time
# working function
def work():
for i in range(10):
print('Working...')
time.sleep(0.2)
if __name__ == '__main__':
# サブ
プロセス work_process = multiprocessing を作成します。 Process(target=work)
# サブプロセスを開始します
work_process.start()
# 1 秒遅延します
time.sleep(1)
# サブプロセスを直接破棄して、実行の終了を示します メインプロセスが終了する前に、すべてのサブプロセスを破棄します-processes 直接 OK
work_process.terminate()
print('メインプロセスは終了しました')
ヒント: 上記の 2 つの方法により、メイン プロセスが終了し、子プロセスが破棄されることが保証されます。
操作結果:
作業中...
作業中...
作業中...
作業中...
作業中...
メインプロセスが終了しました
このコードは、Python のマルチプロセッシング モジュールを使用してサブプロセスを作成し、そのサブプロセスに作業関数 work() を実行させ、メイン プロセスでのサブプロセスの操作と終了を制御します。具体的な説明は以下の通りです。
-
マルチプロセッシングおよび時間モジュールをインポートします。
-
作業関数 work() を定義します。この関数はループ内で 10 回実行され、毎回「Working...」というメッセージを出力し、0.2 秒間スリープします。
-
if name == 'main' 条件文で、ターゲット関数が work() である子プロセス work_process を作成します。
-
サブプロセス work_process を開始します。これにより、 work() 関数内のループ ステートメントの実行が開始されます。
-
メインプロセスは 1 秒遅延し、子プロセスの実行をしばらく待ちます。
-
work_process.terminate()メソッドを呼び出して、子プロセスの実行を強制終了します。
-
「メインプロセスの実行が完了しました」というメッセージを出力します。
全体として、このコードは、Python でマルチプロセッシング モジュールを使用して、サブプロセスの実行と終了を作成および制御する方法を示しています。
六、糸の概念
1. スレッドの概念
Python では、マルチスレッドを使用してマルチタスクを実現することもできます。
2. マルチスレッドを使用する理由は何ですか?
プロセスとはリソースを割り当てる最小単位であり、プロセスを作成すると、QQ ソフトウェアを 2 つ開いて 2 人でチャットするのと同じように、特定のリソースが割り当てられるため、リソースの無駄になります。
スレッドはプログラム実行の最小単位です。実際、プロセスはリソースの割り当てのみを担当し、これらのリソースを使用してプログラムを実行するのはスレッドです。つまり、プロセスはスレッドのコンテナであり、プロセス内の少なくとも 1 つのスレッドがプログラムの実行を担当します。同時に、スレッド自体はシステム リソースを所有せず、動作中に不可欠な少数のリソースのみを必要としますが、プロセスが所有するすべてのリソースを同じプロセスに属する他のスレッドと共有できます。これは、1 つの QQ ソフトウェア (1 プロセス) を通じて 2 つのウィンドウ (2 スレッド) を開いて 2 人でチャットするようなもので、マルチタスクを実現し、同時にリソースを節約します。
3. マルチスレッドの役割
def func_a():
print('タスク A')
def func_b():
print('タスク B')
func_a()
func_b()
☆ シングルスレッド実行
☆ マルチスレッド実行
7、マルチタスクを完了するマルチスレッド
1. マルチタスクを完了するマルチスレッド
①スレッドモジュールをインポートする
import threading
②スレッドクラスを通じてスレッドオブジェクトを作成する Thread object
= threading.Thread(target=タスク名)
②タスクを実行するためにスレッドを開始する
Thread object.start()
パラメータ名 |
説明する |
---|---|
目標 |
実行するターゲットタスクの名前。ここでは関数名(メソッド名)を指します。 |
名前 |
スレッド名。通常は設定する必要はありません |
グループ |
スレッド グループ。現在は [なし] のみを使用できます。 |
2. スレッドの作成と起動コード
シングルスレッドの場合:
import time
def music():
for i in range(3):
print('听音乐...')
time.sleep(0.2)
defcoding():
for i in range(3):
print('敲代码. ..')
time.sleep(0.2)
if __name__ == '__main__':
music()
coding()
マルチスレッドの場合:
import time
import threading
def music():
for i in range(3):
print('听音乐...')
time.sleep(0.2)
defcoding():
for i in range(3):
print('敲代...')
time.sleep(0.2)
if __name__ == '__main__':
music_thread = threading.Thread(target=music)
coding_thread = threading.Thread(target=coding)
music_thread.start()
coding_thread.start()
3. スレッドはパラメータを指定してタスクを実行します
パラメータ名 |
説明する |
---|---|
引数 |
パラメータをタプルの形式で実行タスクに渡します。 |
クワーグス |
実行タスクにパラメータを辞書として渡す |
import time
import threading
def music(num):
for i in range(num):
print('听音乐...')
time.sleep(0.2)
defcoding(count):
for i in range(count):
print( '敲代码...')
time.sleep(0.2)
if __name__ == '__main__':
music_thread = threading.Thread(target=music, args=(3, ))
coding_thread = threading.Thread(target=coding, kwargs ={'カウント': 3})
music_thread.start()
coding_thread.start()
メインスレッドで、music_thread.start() とcoding_thread.start() を通じて 2 つのスレッドを開始し、同時に実行できるようにします。スレッドは並行して実行されるため、music()関数とcoding()関数が交互に実行され、対応する情報が出力されます。
4. メインスレッドとサブスレッドの終了シーケンス
import time
import threading
def work():
for i in range(10):
print('work...')
time.sleep(0.2)
if __name__ == '__main__':
# 子プロセスを作成
work_thread = threading.Thread( target=work)
# スレッドの開始
work_thread.start()
# 1秒遅延
time.sleep(1)
print('メインスレッドが実行されました')
操作結果:
仕事...
仕事...
仕事
...仕事
...仕事...
メインスレッドが終了しました
仕事...
仕事...
仕事...
仕事...
仕事...
このコードは、Python のスレッド モジュールを使用してスレッド work_thread を作成し、work() 関数を実行します。
work() 関数は「work...」を出力し、ループが 10 までカウントされるたびに 0.2 秒間一時停止します。
メインスレッドで、 work_thread.start() を使用してスレッドを開始し、実行を開始できるようにします。
その後、メインスレッドは 1 秒遅延してから、「メインスレッド実行完了」を出力します。work_thread スレッドがすべての作業を完了するのに 2 秒かかるため、メイン スレッドは work_thread スレッドよりも前に実行を終了します。
スレッドを使用すると、複数のタスク間でプログラムを切り替えることができ、プログラムの効率と応答速度が向上します。
☆デーモンスレッドの設定方法1
import time
import threading
def work():
for i in range(10):
print('work...')
time.sleep(0.2)
if __name__ == '__main__':
# サブスレッドを作成し、ガーディアンを設定しますmain thread
work_thread = threading.Thread(target=work, daemon=True)
# スレッドを開始
work_thread.start()
# 1 秒遅延
time.sleep(1)
print('メインスレッドが実行される')
操作結果:
仕事...
仕事...
仕事...
仕事...
仕事...
メインスレッドは終了しました
このコードは、Python の時間モジュールとスレッド モジュールを使用します。
まず、サブスレッドでタスクを実行する関数 work() が定義されます。この関数は 10 回ループし、毎回文字列「work...」を出力し、time.sleep(0.2) を使用してタスクの実行時間をシミュレートします。
次に、メインプログラムでサブスレッド work_thread を作成し、そのターゲット関数として work() 関数を使用し、daemon=True を設定してデーモンスレッドとして設定します。次に、 work_thread.start() を使用して子スレッドを開始します。
次に、メインスレッドは time.sleep(1) を使用して 1 秒間遅延させ、子スレッドがタスクを実行するのを待ちます。最後に、メインスレッドは「メインスレッド実行完了」という文字列を出力します。
子スレッドはデーモンスレッドとして設定されているため、メインスレッドの実行が終了すると子スレッドも終了します。したがって、デーモン スレッドが設定されていない場合、子スレッドはタスクが完了するか手動で停止されるまで実行を続けます。
☆デーモンスレッドの設定方法2
import time
import threading
def work():
for i in range(10):
print('work...')
time.sleep(0.2)
if __name__ == '__main__':
# 子スレッドを作成
work_thread = threading.Thread( target=work)
# ガーディアンメインスレッドを設定します
work_thread.setDaemon(True)
# スレッドを開始します
work_thread.start()
# 1秒遅延します
time.sleep(1)
print('メインスレッドが実行されます')
操作結果:
仕事...
仕事...
仕事...
仕事...
仕事...
メインスレッドは終了しました
このコードは、Python のスレッド モジュールを使用して子スレッドを作成し、それをガーディアンのメイン スレッドとして設定し、子スレッドを開始します。子スレッドの仕事は、「work...」文字列を出力して 0.2 秒間スリープし、それを 10 回繰り返すことです。
メインスレッドでは、コードは 1 秒の遅延後に文字列「メインスレッドの実行が完了しました」を出力します。子スレッドはメインスレッドを保護するように設定されているため、メインスレッドの実行が終了すると、子スレッドも終了します。
サブスレッドがガーディアンメインスレッドとして設定されていない場合、メインスレッドの実行後、サブスレッドはすべての作業が完了するまで実行を続けます。
5. スレッド間の実行順序
range(5) の i の場合:
sub_thread = threading.Thread(target=task)
sub_thread.start()
考えてみます: プロセス内に複数のスレッドを作成する場合、スレッドはどのように実行されるのでしょうか? 順番に?一緒に実行しますか?それとも他の実装方法でしょうか?
回答: スレッド間の実行順序が間違っています。確認してください。
☆ 現在のスレッド情報を取得する
# current_thread メソッドを通じてスレッド オブジェクトを取得します
current_thread = threading.current_thread()
# current_thread オブジェクトを通じて、スレッドの作成順序などの関連情報を知ることができます
print(current_thread)
☆スレッド間の実行順序
import threading
import time
def get_info():
# 効果を確認するために一時的に追加することはできません
time.sleep(0.5)
current_thread = threading.current_thread()
print(current_thread)
if __name__ == '__main__':
# サブ
range(10) の i のスレッド:
sub_thread = threading.Thread(target=get_info)
sub_thread.start()
概要: スレッド間の実行は順序が狂っており、特定のスレッドが最初に実行されることが CPU スケジューリングによって決定されます。
6. スレッド間でグローバル変数を共有する
☆ スレッド間でグローバル変数を共有する
複数のスレッドが同じプロセス内にあり、複数のスレッドが使用するリソースは同じプロセス内のリソースであるため、マルチスレッドはグローバル変数を共有します
サンプルコード:
インポートスレッド
インポート時間
my_list = []
def write_data():
for i in range(3):
print('add:', i)
my_list.append(i)
print(my_list)
def read_data():
print('read: ', my_list)
if __name__ == '__main__':
write_thread = threading.Thread(target=write_data)
read_thread = threading.Thread(target=read_data)
write_thread.start()
time.sleep(1)
read_thread.start()
操作結果:
追加:0
追加:1
追加:2
[0, 1, 2]
読み取り:[0, 1, 2]
これは、Python のスレッド モジュールを使用したマルチスレッド プログラミングの例です。
このコードは、空のリスト my_list へのデータの追加とリスト内のデータの読み取りをそれぞれ実装する 2 つの関数 write_data() と read_data() を定義します。
このコードでは、write_thread と read_thread という 2 つのスレッドも定義されており、それぞれデータの書き込みとデータの読み取りという 2 つのタスクを実行するために使用されます。プログラムの main 関数で、最初に write_thread と read_thread にそれぞれ write_data() 関数と read_data() 関数を指定し、start() を呼び出して write_thread スレッドを開始し、read_thread スレッドが開始するまで 1 秒待機します。
プログラムが実行されると、write_thread と read_thread という 2 つのスレッドが同時に実行されます。write_thread は my_list リストにデータを追加し、read_thread は my_list リストを読み取って出力を出力します。スレッド間には同期がないため、raceつまり、書き込みと読み取りの順序は不定です。
7. 概要: プロセスとスレッドの比較
☆関係比較
① スレッドはプロセスに接続されており、プロセスのないスレッドは存在しません。
② プロセスはデフォルトで 1 つのスレッドを提供しますが、プロセスは複数のスレッドを作成できます。
☆違いと比較
①グローバル変数はプロセス間で共有されない
②スレッド間でグローバル変数を共有する
③プロセス作成時のリソースオーバーヘッドがスレッド作成時のリソースオーバーヘッドより大きい
④プロセスはオペレーティングシステムのリソース割り当ての基本単位、スレッドはCPUスケジューリングの基本単位です
☆メリット・デメリットの比較
①プロセスのメリットとデメリット: メリット:マルチコアが利用可能 デメリット:リソースオーバーヘッドが高い
②スレッドのメリットとデメリット メリット:リソースのオーバーヘッドが少ない デメリット:マルチコアが利用できない