Pythonプロセスとスレッドインタビューの経験の概要
毕业季当下的你,还在为米那是烦恼吗?下面给大家带来Python进程线程的面试总结
記事のディレクトリ
プロセス、スレッドの概念
-
プロセスとスレッドの関係
-
进程
コンピューターでのプログラムの1回限りの実行。
プログラムは実行可能ファイルであり、ディスクを静的に保持します。
プロセスは動的なプロセス記述であり、コンピューターの操作リソースを占有し、特定のライフサイクルを持ちます。
-
プロセスの状態
-
準備完了状態:プロセスには実行条件があり、CPUリソースを割り当てるためのシステムスケジューリングを待機します
-
実行状態:プロセスはCPUを占有し、実行中です
-
待機状態:プロセスはブロックされて待機しており、この時点でCPUが解放されます
-
5つの州(3つの州に基づいて新規および終了を追加)
新建 : 创建一个进程,获取资源的过程 终止 : 进程结束,释放资源的过程
-
-
线程
スレッドは軽量プロセスと呼ばれ、マルチタスクプログラミングメソッドでもあります
コンピューターのマルチCPUリソースを使用することもできます
スレッドは、プロセスで再開されたブランチタスクとして理解できます。
-
糸の特徴
-
プロセスには複数のスレッドを含めることができます
-
スレッドも実行動作であり、コンピューターリソースを消費します
-
プロセス内のすべてのスレッドは、このプロセスのリソースを共有します
-
複数のスレッドの操作も互いの操作に影響を与えません
-
スレッドの作成と破棄は、プロセスよりもはるかに少ないリソースを消費します
-
-
プロセスはリソース割り当ての最小単位であり、スレッドはCPUスケジューリングの最小単位です
スレッドとプロセスの違いは、次の4つのポイントに要約できます。
-
アドレス空間およびその他のリソース(ファイルを開くなど):
プロセス間
相互独立
で、同じプロセス各线程间资源共享
。プロセス内のスレッドは、他のプロセスでは表示されません。
-
通信:
プロセス間通信IPC、スレッドは通信プロセスの同期のためにプロセスデータセグメント(グローバル変数など)を直接読み書きできます。データの一貫性を確保するには、相互排除手段が必要です。
-
スケジューリングと切り替え:
线程
コンテキストの切り替えは、进程
コンテキストの切り替えよりも重要です快得多
。 -
マルチスレッドOSでは、プロセスは実行可能エンティティではありません。
マルチプロセスとマルチスレッドの比較
コントラスト寸法 | マルチプログレス | マルチスレッド | 総括する |
---|---|---|---|
データの共有と同期 | 複雑なデータ共有と単純な同期 | データ共有は簡単で、同期は複雑です | それぞれに長所と短所があります |
メモリ、CPU | メモリ多 、複雑なスイッチング、およびCPU使用率を占有します低 |
メモリ少 、簡単な切り替え、CPU使用率を占有します高 |
スレッドの優位性 |
作成、破棄、切り替え | 复杂,速度慢 |
简单,速度快 |
スレッドの優位性 |
プログラミング、デバッグ | 簡単なプログラミングとデバッグ简单 |
複雑なプログラミング、デバッグ复杂 |
プロセスの優位性 |
信頼性 | プロセスは互いに影響しません | スレッドがハングすると、プロセス全体がハングします | プロセスの優位性 |
配布 | マルチコア、マルチマシンに適しており、複数のマシンに簡単に拡張できます | マルチコアに適しています | プロセスの優位性 |
进程与线程总结
- スレッドはプロセス中にダウンします(純粋なキャリッジは実行できません)
- プロセスには複数のスレッドを含めることができます(トレインには複数のキャリッジを含めることができます)
- 異なるプロセス間でデータを共有することは困難です(駅の乗り換えなど、ある列車の乗客を別の列車に乗り換えるのは困難です)
- 同じプロセス内の異なるスレッド間でデータを共有するのは簡単です(キャリッジAはキャリッジBに簡単に変更できます)
- プロセスはスレッドよりも多くのコンピューターリソースを消費します(複数のトレインは複数のキャリッジよりも多くのリソースを消費します)
- プロセスは相互に影響しません.1つのスレッドがハングすると、プロセス全体がハングします(列車は他の列車には影響しませんが、列車の真ん中の車が燃えている場合は、電車。)
- このプロセスは複数のマシンに拡張でき、プロセスは最大で複数のコアに適しています(異なる列車を複数のトラックで運転でき、同じ列車の車両を異なるトラックで運転することはできません)
- プロセスで使用されるメモリアドレスはロックできます。つまり、スレッドが共有メモリを使用する場合、他のスレッドはこのメモリを使用する前に、その共有メモリが終了するのを待つ必要があります。(電車のトイレなど)-「ミューテックス」
- プロセスで使用されるメモリアドレスは、使用量を制限する可能性があります(たとえば、電車のレストラン、入場できる最大人数、満員の場合は、ドアで待って、誰かが入る前に出てくる)-「セマフォ」
プロセスプログラミング
-
モジュールの使用:マルチプロセッシング
-
作成プロセス
-
新しいプロセスで実行する必要のあるイベントを関数にカプセル化します
-
モジュールのProcessクラスを介してプロセスオブジェクトを作成し、関数を関連付けます
-
プロセス情報と属性は、プロセスオブジェクトを介して設定できます
-
プロセスオブジェクト呼び出しstartを介してプロセスを開始します
-
プロセスオブジェクトを介してjoinを呼び出し、プロセスリソースを再利用します
-
"""
multiprocessing
1.将需要新进程执行的事件封装为函数
2 .通过模块的Process类创建进程对象,关联函数
3 .通过进程对象调用start启动进程
4 .通过进程对象调用join回收进程资源
"""
import multiprocessing as mp
from time import sleep
a = 1
# 进程函数
def fun():
global a
print("开始一个进程")
sleep(2)
a = 1000
print("a = ",a)
print("进程结束了,实际也没干啥")
if __name__ == '__main__':
# 创建进程对象
p = mp.Process(target=fun) # 绑定函数 此时还没有创建进程
# start启动进程 自动执行fun函数,作为一个进程执行
p.start() # 此时进程才产生
print("原有进程也干点事")
sleep(3)
print("原有进程其实也没干啥")
# 回收进程
p.join()
print("a :",a) # a = 1
スレッドプログラミング
-
作成手順
-
Threadクラスを継承します
-
__init__
メソッドをオーバーライドして独自のプロパティを追加し、super()を使用して親クラスのプロパティをロードします -
run()メソッドをオーバーライドします
-
-
指示
-
オブジェクトをインスタンス化します
-
startを呼び出して、runメソッドを自動的に実行します
-
スレッドをリサイクルするには、joinを呼び出します
-
"""
threading 创建线程演示
"""
from threading import Thread
from time import sleep
import os
a = 1 # 全局变量
# 线程函数
def music():
for i in range(3):
sleep(2)
print(os.getpid(),"播放:黄河大合唱")
global a
print("a =",a)
a = 1000
# 创建线程对象
t = Thread(target=music)
t.start() # 启动线程 执行music
for i in range(4):
sleep(1)
print(os.getpid(),"播放:葫芦娃")
t.join() # 回收线程资源
print("a:",a)"""
threading 创建线程演示
"""
from threading import Thread
from time import sleep
import os
a = 1 # 全局变量
# 线程函数
def music():
for i in range(3):
sleep(2)
print(os.getpid(),"播放:黄河大合唱")
global a
print("a =",a)
a = 1000
# 创建线程对象
t = Thread(target=music)
t.start() # 启动线程 执行music
for i in range(4):
sleep(1)
print(os.getpid(),"播放:葫芦娃")
t.join() # 回收线程资源
print("a:",a)
ゾンビと孤児
-
孤立したプロセス:親プロセスは子プロセスの前に終了し、この時点で子プロセスは孤立したプロセスになります。[両親を亡くした場合、父親が先に撤退します]
- 特徴:孤立プロセスはシステムプロセスに採用されます。この時点で、システムプロセスは孤立プロセスの新しい親プロセスになり、孤立プロセスはプロセスを終了すると自動的に処理されます。
-
ゾンビプロセス:子プロセスは親プロセスの前に終了し、親プロセスは子プロセスの終了ステータスを処理しません。このとき、子プロセスはゾンビプロセスと呼ばれます。
-
機能:ゾンビプロセスは終了しますが、一部のプロセス情報リソースはメモリに残り、多数のゾンビプロセスはシステムメモリリソースを浪費します。
-
ゾンビプロセスを回避する方法
- join()を使用してリサイクルする
- 親プロセスでsignalメソッドを使用して、[ウィンドウの下では使用できません]を処理します。
-
"""
孤儿进程和僵尸进程演示
"""
from multiprocessing import Process
from time import sleep
import os
from signal import *
def fun():
print("这是一个子进程",os.getppid(),'---',os.getpid())
sleep(3)
print("注定成为孤儿进程", os.getppid(), '---', os.getpid())
if __name__ == '__main__':
signal(SIGCHLD,SIG_IGN) # 系统方法处理僵尸进程,所有子进程退出由系统处理
p = Process(target=fun)
p.start()
p.join() # 防止僵尸产生
# 大量工作进入死循环
while True:
pass
デッドロック
- デッドロックとは、リソースの競合や実行プロセスでの2つ以上のスレッド間の通信によって引き起こされるブロッキング現象を指し、外力がないと前進できません。このとき、システムがデッドロック状態にあるか、システムにデッドロックがあると言われています。[ロジックの混乱により、複数のロックが相互にブロックし、プログラムの実行に失敗します]
-
デッドロック状態
-
相互排除条件:相互排除方式を使用するスレッドを指します。リソースを使用する場合、他のスレッドはそれを使用できません。【三者が金銭を支払うという問題は論理的に解決される】
-
要求と保持の条件:少なくとも1つのリソースを保持しているが、新しいリソース要求を行ったスレッドを指し、新しいリソースを取得する前に保持しているリソースを解放しません。
-
非剥奪条件:システムがスレッドを強制的に終了するなど、スレッドの外部からの干渉がないこと。
-
ループ待機状態:デッドロックが発生した場合、スレッドが存在する必要があります。たとえば、T0はT1が占有するリソースを待機し、T1はT2が占有するリソースを待機し、...、Tnは待機しています。占有されているT0リソースの場合。
-
-
デッドロックを回避する方法
- ロジックは明確であり、上記のデッドロックによって引き起こされる4つの条件が同時に発生することはありません。
- テストエンジニアによるデッドロックの検出
GILグローバルインタプリタロック
-
GILの問題(グローバルインタープリターロック)とは何ですか[Pythonスレッドは無味です、8ではありませんか?】
インタープリターロックがPythonインタープリターの設計に追加されているため、Pythonインタープリターは一度に1つのスレッドしか解釈および実行できず、スレッドの実行効率が大幅に低下します。
-
スレッドが閉塞に遭遇すると、他のスレッドを説明するためにインタプリタを積極的に放棄するため、これは結果につながります。したがって、Pythonマルチスレッドは、マルチブロッキングタスクを実行するときにプログラムの効率を向上させることができ、他の状況では効率を向上させることはできません。[マルチスレッドは、スリープブロッキングを通じてマルチスレッドの効率を向上させます]
[直接的な結果:同時に説明できるスレッドは1つだけです]
[効率:非ブロッキングタスクを処理するときの効率が低い]
[結論:Pythonスレッドは、ブロッキングレイテンシが高いタスクを効率的に処理する場合にのみ適しています]
-
GILの問題の提案
* 尽量使用进程完成无阻塞的并发行为
* 不使用c作为解释器 (Java C#)
Guido的声明:<http://www.artima.com/forums/flat.jsp?forum=106&thread=214235>
- 結論として
- GILの問題は、Python言語自体とは何の関係もありません。これは、インタープリター設計の歴史的な問題です。
- 非ブロッキング状態では、マルチスレッドプログラムの実行効率は高くなく、シングルスレッドほど効率的でもありません。
- Pythonマルチスレッドは、ブロッキング遅延のあるタスクの実行にのみ適しています。