リソースの割り当てとスケジューリングのためのプロセスシステムの基本単位
スレッドシステムの独立したスケジューリングとディスパッチの基本単位は、CPUスケジューリングの最小単位(プログラム実行フローの最小単位)です。
プロセスの切り替えには、最も多くのリソースと最も低い効率が必要
スレッドの切り替えには、平凡なリソースと平凡な効率が必要です(もちろんGILを考慮していません)。
コルーチン切り替えタスクのリソースは小さく効率的で、コルーチンはマイクロスレッドとも呼ばれます
CPUコアの数によっては、マルチプロセスとマルチスレッドは並列になる場合がありますが、コルーチンは1つのスレッド内にあるため、同時に実行されます。
同時実行性:複数のスレッドが実行されている場合、システムにCPUが1つしかない場合、タスクを実行するために複数のスレッドに適度に割り当てられ、より高速なマルチ割り当てを実行し、実行速度を遅くします。
並列:システムに複数のCPUがある場合、スレッドは、互いにリソースを先取りすることなく異なるCPUに割り当てられます。
並行性と並列性の最大の違いは、それらが同時かどうかです。
マルチプロセス:システムで複数の異なるタスクを同時に実行します
マルチスレッディング:1つのプログラムで複数の異なるタスクを同時に完了する
違い
プログラムには少なくとも1つのプロセスがあり、プロセスには少なくとも1つのスレッドがあります
プロセスはグローバル変数を共有せず、スレッドはグローバル変数を共有できます
スレッド自体はシステムリソースを所有しておらず、操作に不可欠なリソースが少ししかありませんが、同じプロセスに属する他のスレッドと共有できます
マルチスレッド(共有グローバル変数)
スレッドインポートからスレッド
インポート時間
def work1(nums):
nums.append(44)
print( "---- in work1 ---"、nums)
def work2(nums):
#t1スレッドの処理が確実に終了するまでしばらく遅延します
。sleep(1)
print( "---- in work2 ---"、nums)
g_nums = [11,22,33]
t1 = Thread(target = work1、args =(g_nums、))
t1.start()
t2 = Thread(target = work2、args =(g_nums、))
t2.start()
おわりに
1つのスレッドのすべてのスレッドでグローバル変数を共有すると、複数のスレッドがデータを共有するのに便利ですが、グローバル変数を変更すると、複数のスレッド間で混乱が生じます(つまり、スレッドは安全ではありません)。
複数のスレッドが同時にグローバル変数を操作すると、リソース競合の問題が発生し、データの結果が不正確になります。
ミューテックス
目的:複数のスレッドが特定の共有データをほぼ同時に変更する場合、同期制御が必要です
利点:重要なコードの一部がスレッドによって最初から最後まで完全にしか実行できないようにする
短所:複数のスレッドの同時実行を防止します。ロックを含むコードの特定のセクションはシングルスレッドモードでのみ実行できます。複数のロックが存在する可能性があるため、効率が大幅に低下し、異なるスレッドが異なるロックを保持します。ビューが相手が保持しているロックを取得すると、デッドロックが発生する可能性があります
#ロック
ミューテックスを作成 = threading.Lock()
#
mutex.acquireをロック()
#
mutex.release()を解放する
デッドロックを回避する
1.プログラムの設計中にそれを回避するようにしてください(銀行のアルゴリズム)
2.タイムアウトを追加する
プロセス
プロセスを作成する1つの方法:
マルチプロセッシングからのインポート時間import Process def test(): "" "子プロセスによって個別に実行されるコード" "" while True: 印刷( '---- test ----') time.sleep(1) #1秒間スリープBell if __name__ == ' __main__ ': p = Process(target = test) #関数の名前をプロセスのターゲットに渡すと、関数への参照が指定されます p.start() #この文の実行時にプロセスが作成されますプロセス#メインプロセスがコード を実行している間、True: print( '---- main ----') time.sleep(1)
要約:
1.追加のプロセスを作成することにより、マルチタスクを実現するプロセスを使用してマルチタスクプロセスを実現できます。
2.プロセスオブジェクトを作成し、作成中にターゲットによって関数参照を指定する
3. startが呼び出されると、実際には子プロセスが作成されます
プロセスによって作成されたインスタンスオブジェクトの一般的なメソッド:
1.start():サブプロセスインスタンスを開始(サブプロセスを作成)
2.is_live():子プロセスがまだ生きているかどうかを判断します
3.join([timeout]):子プロセスの実行が終了するまで待つか、何秒待つか
terminate():タスクが完了したかどうかに関係なく、子プロセスを直ちに終了します
プロセスを作成する2番目の方法:
import time
from multiprocessing import Process
# 方法二:
class MyProcess(Process):
def run(self):
while True:
print('----1----')
time.sleep(1)
if __name__ == '__main__':
p = MyProcess() # 创建一个MyProcess的对象
# 当执行到这一句话的时候 会调用p.start()方法,p会先去父类中寻找start(),然后再Process的start方法中调用run方法
p.start()
while True:
print('----main----')
time.sleep(1)