#328 マルチスレッド、マルチプロセス、asyncioのお話
2025/2/9 ·
-
この番組はエンジニアの成長は楽しい学びからをもとにエンジニアリングに関する学びをワイワイお届けするラジオですということで本日なんですがブログ記事の紹介なんですけどブログ記事ディープダイブイントゥマルチスレッティングマルチプロセッシングアンドアシンクアイオーっていう記事をちょっと紹介させていただきたいです
-
マルチプロセッシングの話ですねそうですねマルチスレッドマルチプロセスあとはPythonのライブラリなんですけどAsyncIOつながりましてなんでPythonの世界の中でのマルチスレッドマルチプロセスAsyncIOっていう話ですとちなみにデュオリンゴマスターとして一個いいですかAsyncらしいですよこれAsyncなの?
-
ASYNCIOASYNCIOJSとかだとさASYNCとAWAITってあるじゃないですかどっちもAから始まってるのにASYNCとAWAITらしいですよありがとうございますこれそもそもASYNCIOだよなさすがに海外の動画見ててそういう発音するんだと思った記憶ある海外の動画見てるんですか
-
すげーいつ見てんのたまにこうやっていうことによってのりさんが訂正してくれるので勉強になりますね前もなんかあった気がするなんだっけなんかありましたasyncらしいですねなので今日はマルチプロセスマルチスレッドこれはベースですベーシックですけど違いが分かったりとかあとはパイソンの独自のasyncioつながりますけど多分
-
他の言語でも一緒なのかなわかんないですけどその仕組みを話してパイソンこうなってんだなっていう雑学みたいなものとかあとはコンピューターの仕組み的なところですねプロセススレッドの違いって具体的に何みたいなところ混ざりがちその辺の話できればなと思いますはい
-
一回ちょっと今の認識聞いてみていいですか順平にマルチプロセスとマルチスレッドプロセスは処理が例えば3つぐらいあったとしてスタックしてしまう処理AがBって進んでって途中で処理次のがB C入ってきてもAの途中までは
-
行ってちょっとキリいいなってなったら次ちょっとB始めてでまたAに戻ってみたいなどうかマルチプロセスとさせてくださいはいスレッドはその処理ABCを同時に進めてるはいえーと多分
-
どっちも違うかな 並列すると平行処理の違いかなそれはどっちも違うってよカットしちゃダメですかここカットしてもいいよカットするかだいぶ違います?だいぶ違いました?わかんない俺も正直わかんないじゃあ行きますねじゃあ今日の話する意味ありますわはい行きますじゃあちょっとあの
-
ベースというか基礎の部分今日の話を理解する上で必要な基礎部分から走り始めるんですけどまずプログラムの処理部分の話なんですがマルチプロセスマルチスレッド以前にコンカレンシーというか同時実行制御というのがあるんですけど普通に実行するときですね
-
コンピューターって複数の処理を同時にやってるように見えるんですけど実は細かく切り替えてやってるだけだよねっていうのあるじゃないですかABCっていうタスクがあった時にそれぞれ同時にやってるように見えるけど実はAとBとCの作業を細かくババババババって切り替えながらやってるからどっちもどっちもっていうか全部やってるように見える同時実行制御っていうものがまずありますとなるほど
-
一方でさっきじゅんぺいが言ってたのは並列処理ですね並列処理は複数のCPUコアを使って複数のタスクを同時に実行することなんで3人の人が3つの作業をやる状態ですね最初に言ったやつは1人の人が3つの作業を切り替えながらやっていくこういう作業がまずありますとで
-
次ちょっとプロセスとはっていう話に入っていくんですがプロセスっていうのは実行しているものものというか実行していることなんですけどちょっと具体的に言うとプログラムあるじゃないですかプログラムのコードこれはプログラムのコードっていう静的なファイルっていうんですかねテキストファイルみたいなねこれはOSがメモリにロードして
-
で実行した時にプロセスと呼ばれるようになります動いてるやつ実行中のスクリプトみたいな感じですかまあそうですねスクリプトのことを指すというよりは動いてるやつ動いてるやつプロセスっていうのは自分自身で自分のメモリとかメモリ領域かリソースとか実行状態っていうのを持ちますとでプロセスっていうのはまあ
-
基本的にはお互いに独立しているようなものですなので2つプロセスがあったらそのプロセス間での通信っていうのは明示的に設定とかしない限りはない独立してるお互いになんだろうだから同じメモリ領域も触らないはいなるほどなんて言うんでしょうねビュッフェで言うとキッチンみたいなキッチンが独立してますみたいな
-
キッチンが独立しています2つプロセスがある状態はキッチンが2つあってそのキッチン同士のやり取りは発生しませんこれがマルチプロセスみたいなものですねプロセスっていうのはここちょっと僕ブログ記事読んでた確かにこの考えあるなっていうところなんですけど2種類あります白って200色あんねんみたいな感じでプロセスって2色あるねん少なさあ問題です何と何え
-
実行中のやつと待機中のやつありがとうございますステイトーの話ですけどちょっと違くてですね違ったIoBoundProcessとCPUBoundProcessこの2つに分かれるわけなんですねちょっと聞いたことがあるかもしれないですがIoBoundProcessっていうのはファイルアクセスネットワーク通信ユーザー入出力みたいな感じで街とかが発生するようなやつ
-
これ待ってるときはCPUはアイドル状態空いてますになりますねもう一個のCPUバウンドプロセスっていうのが計算めっちゃ使いやつ動画のエンコーディング作業とかあと何かの解析とか多分機械学習の学習とか推論とかこういうのがCPUバウンドプロセスと呼ばれますCPUバウンドプロセスとかってボトルネックの話?
-
ボトルネックな話なんか処理が重いよっていう時にそのIo側が問題になってるやつをIoバウンドプロセスって言ってCPU側が問題になって遅くなってる時をCPUバウンドプロセスっていうようなイメージがあるどうなんでしょう調べた上でそれにめっちゃ時間をかけてるプロセスはCPUバウンドプロセスって言ってるようでしたなるほどで
-
この2つに分かれますこれも今後のマルチスレッドとかマルチプロセスアシンカイオーこれ最終的にはどういう時にどれを使うべきかみたいなところに落とし込んでいくんですけどその選ぶ勘どころとしてちょっとこの辺が大事になってきますさっきのりさんが最初言ってたレディ状態とかって言ってたのは多分プロセスのステイトライフサイクルかの話
-
だと思っててこれはちょっとあんまり関係ないんでさらっと流すんですけどプロセス作られた時はnewっていう状態になってで、CPUnewになったらCPUが割り当てられるまではレディ状態で、割り当てられて処理してる処理され始めてIoで待ってる時はwaitingとか終わったらterminateみたいな感じでプロセスは生まれてそして死んでいくみたいな有限状態機械って言うんですね
-
オートマトンこれプロセスの簡単な紹介でした次スレッド
-
これ日本語訳すると糸らしいですけど日本語訳なんでこれも僕初めて知ったんですけど図解するとスレッドって糸で書かれるんですねえ、そうなの?プロセスって割と四角で表されるじゃないですかスレッドをニョロニョロニョロっていうそうなんだこういう図をちょっと散見しましたそういう世界があるってだけなんですけどで、スレッドっていうのはプロセスに所属されているものです
-
プロセスの中にいるやつです全てのプロセスは一つがスレッドを持ちます少なくともこれメインスレッドってやつですねマルチスレッドだったら一つのプロセスが複数のスレッドを持つかもしれないようなものですここがプロセスとの違いなんですけど
-
プロセスの中にスレッド入ってるじゃないですかなのでスレッドはプロセスと同じメモリとかリソースを共有してますプロセスとスレッドはだからなんか通信しやすいですだからマルチスレッドの場合もスレッド同士が一つのプロセスの中に入ってるんで通信しやすいです同じリソースを使ってますなんでビュッフェで言うと
-
一つの厨房の中に複数人人がいる状態ですねシェフだシェフかスタッフかなるほどねマルチプロセスがビュッフェ1ビュッフェ2でマルチスレッドがビュッフェ1にいるたくさんの作業員ってことビュッフェというかキッチンというかキッチン
-
あのー杉の井ホテルというホテルベップ温泉のホテルがあるんですけどあそこのビュッフェを思い出していただいてあそこビュッフェ会場1個なんですけど多分キッチン複数あったと思うんですねビュッフェ会場いっぱいいなかったっけあそこビュッフェ会場のなんかがあったそこ多分マルチプロセスマルチスレッドだよねマルチプロセスマルチスレッドですわかる人は多分ほぼほぼいないと思うんですけどいないよねほぼほぼいないベップ温泉行って一番はしゃげるホテルだと思うんですけどそうねー
-
でも大体の世の中のホテルはシングルプロセスマルチスレッドですよね大体夕食会場とか1個じゃないですか多分そうっていう話ででちょっと戻りましてなのでマルチスレッドってマルチプロセスより注意が必要なんですよ一つの
-
キッチンでやり取りしてるんで一つのメモリ領域とかでやり取りしてるんでデッドロックとか競合とかが発生するんですねデッドロック競合って何を言ってるかっていうとまずデッドロックこれは二つの例えばスレッドがお互いの仕事を邪魔し合ってどっちも動かなくなるみたいな状態ですねキッチンで
-
一人の人が人参を切ってますとただ人参はこれ今切らなくてもいいと洗い場が開くまで切ってよで人参を切ってますと一方洗い場の人キッチンでのまな板が開くまで
-
このお皿を洗ってよまな板開かなかったらここの洗い場洗ってよみたいな状態の時に一生人参を切ってる人と一生洗い場を洗ってる人が誕生するんですねうん確かにこうなると全てが止まりますビュッフェも提供できませんただ人参だけが増えてきますあと綺麗なお皿ね綺麗なお皿とピカピカの流しはいこれはデッドロックという状態ですねはい
-
で、競合もですね競合ちょっとどうやって言えばいいかよくわかんないんですけどうんうわーここに物置いてたのにないーって言ってパニックになって爆発するみたいなマジで?急に適当な例えになった同じコンロを使いたがるみたいな一個のフライパンに二つの料理入れちゃったみたいなあーめっちゃいいっすねそれそうしましょうそうだねで入れちゃってうん
-
泣いちゃうんだ泣いちゃって料理長に泣きついて料理長がてんやわんやするっていう状態ですよね料理長はね切れるよマジで料理長切れますか切れるよだいたいっていうのが今のでスレッドとプロセスの空気感なんかなんとなく伝わったかなと思うんですけど
-
ちょっとここから若干Pythonの世界観に入っていくんですがAsyncIOっていうのを話をするためにPythonちょっとどういう言語か一回思い出す思い出しますPythonってコンパイルいらないやつじゃないですかインタープリターってことじゃないですかインタープリターなんでしょうか直で動く
-
まあまあまあダイレクトアタックってことね遠からずですけどえっとプログラムってどうやって動いてると思いますか電気信号電気信号の前にどうなってますか電気信号の前に命令を出すどんな感じでどんな感じでどういう形式で01
-
その手前まで行ってほしいな多分その手前どこだ言っちゃうんですけどいわゆる機械語みたいなものに変換される必要があるんですねだからPythonのコードとかありますけどあれそのまま実行してるわけではなくてですね一回変換する必要があるんですねいわゆるコンパイルもそういう作業をやってると思うんですけどそれを一行一行都度やって実行していくのがインタープリターの
-
動きになりますね言語のだからいわゆるパイソン遅いとか言われるのはインタープリタだからよねみたいな最初から変換して機械語だったらすぐさっと実行できるけど一度翻訳してみたいなっていうのがここにかかってくるインタープリタってやつなんですけど
-
でPythonそのインタープリターの仕組みの中の一環としてGILっていうグローバルインタープリターロック2のがありましてこれ何かというとですねそのPythonのインタープリター内で実行されるスレッドが
-
一つだけであるように制御するやつがいるんですよスレッドかそうですスレッドマルチにならないようにするやつなんでそんなことしてるかっていうとリソースの競合とかそういうのをさせないためなのでPythonでコーディングをしててマルチスレッドをしようとすると実はそのGILに阻まれてマルチスレッドになってないみたいなことがあるわけなんですねそんな場合
-
なんかめっちゃ困るじゃないですかっていうので生まれたのがAsyncIOというものになりますでこのAsyncIOこれはPythonのライブラリなんですけど何をやってるかを話す前にビュッフェで言うんですけど概要をつかむためにAsyncIOはですね一つのキッチンに一人だけいて作業している状態です
-
ブラックじゃないですかブラックかもしれないでえーなんだろうな普通のシングルスレッドの処理とは違ってですねレンジ待ってる間にえー
-
洗い物とかしてます忍者じゃないですか忍者かな効率的に切り替えれる人間です賢いやつってことシングルスレッドの状態は電子レンジの前でまだかなーって待ってるんですけどバカだシングルスレッドの前はねエーシンカー用の場合は電子レンジ温めてる間によしじゃあこれをやってる間に
-
あれもかたしちゃおうって言ってかたしてますなるほど食洗機が回ってる間に人参切っちゃおうってことねそうそうそうそうこれが英心解読ですねでちょっとやや仕組みもせっかくなんで話そうっていうのでちょっと難しい単語が続くかもしれないですがやってることはさっきのキッチンの例でほぼほぼ隅なんですけど仕組みとしてはコルーチンっていう
-
コルーチンっていうやつがいてこれは関数ですねどういう字COルーティン子供の子じゃないのねCOルーティンこれ関数ですねプログラムのコードを思い浮かべてもらってこれ関数がありましてこの関数は一時停止したりとか再開できるものになりますさっきでいう電子レンジみたいな電子レンジで物を温めるときって
-
ピッとしたら動いてるけど後回しにするみたいな状態じゃないですか後回しにして温まったらもう一回取りに行くみたいなこれがコルーチンですねこれがコルーチンイベントループイベントループは何やるか決めるやつです本人ってこと?本人の意思本人の意思かっこよタスクこれはちょっと分かりづらいんですけどコルーチンのラッパーですね
-
なんでコルーチンをやろうと思ったらタスクで一回包んであげて電子レンジで温めるっていう気持ちを持ってるけど書き出さないとできないんで書き出してタスクになる感じですねで最後これアウェイトっていうのがあるんですけど
-
このアウェイトは多分他の言語でもよく使うようなアウェイトですねコルーティンの実行を止めて制御をイベントループに戻すっていう風に説明では書いてたんですけど待つというか待ち時間でちゃんと一回置いとくための呪文みたいなもんですねちゃんと前の処理が終わったら実行してくれるやつそうそうそうそうはい
-
なるほどだからレンジでチンするっていう工程を踏んでないとできない次の作業をアワイトするってことですねですですこれ多分ノードとかでも同じような書き方はしますよねそうですねJSよく使うイメージありますねJSよく使うと思うんですけどで
-
なのでちょっとどうしようかな細かく話をしようかさっきのレンジの例を考えつつちょっとそれぞれどういう風に使われるかをさらっといくんですけどレンジで物を温めるっていう関数がありますこれはメイン関数の下に紐づくやつですねメインでは多分レンジ温める人参を切る終わりにしましょうかやべえ
-
メイン関数メイン関数はレンジ温めるレンジ温めるカット人参リターンほかほかカット人参人参温めてないんだほかほかの何かと切られた人参なるほどさすがに何か作りたいな簡単なやつポテトサラダとかどうですかジャガイモ温めてクラッシュしてマヨネーズ和え
-
じゃあマヨネーズ測っておきますかレンジで温めてる隙になるほどレンジで温めるに引き数じゃがいもですねでマヨネーズ測るレンジで温めたものとマヨネーズ渡してぐしゃぐしゃにするリターンポテトサラダですねアワイトミックスリターンポテトサラダそうそうそうそうはい
-
これで伝わった?わかりましたわかりましたプログラムの流れはねはいはいで他の言語にもあるかもしれないんですけどこのアシンクIO普通に書いたらさっきの流れになるじゃないですか最初にアウェイトでレンジ温めるジャガイモうんじゃないかアウェイトはVIXかなそうですねだからPythonのはい
-
さっきのキッチンの流れの処理をちょっと書いていくとPythonだとですね平行処理したいやつさっきで言うとレンジで松野とマヨネーズ測るこの2つの関数を引数に渡してクリエイトタスクっていうのをやりますクリエイトタスククリエイトタスクっていうのでタスクを作るんですけどそのタスクは2つ入ってます2つ渡してるからってことですか2つ渡してえー
-
タスクの実行をしますとアシンクアイオーギャザーつながってギャザーこれをやると2つ並列でやってくれます中身はレンジ待ち時間でマヨネーズやってくれたりしますその2つが終わったら出てきたあったかポテトとマヨネーズくしゃくしゃに混ぜてポテトサラダを出すみたいなそんな流れになっておりますとなるほど
-
効率よく実行させたやつをクリエイトタスクで包んであげるっていう感じなんですねっていうような形でAsyncIO動いていくんですがマルチスレッドとの違いというか使いどころの差は分かりづらくないですか
-
確かにシングルスレッドでマルチスレッドでやることをやってるように見えてしまうはいそうですよね元々のモチベーション的にもねPythonがそもそもマルチスレッドそんなにやってくんないやってくんないからAsyncIOっていうのを導入してみたいなところが背景としてあるんですけど
-
この今紹介している記事でどういう時にそれぞれマルチスレッドマルチプロセスエーシンクIを使えばいいのかみたいなのを教えてくれてますそれを見ていくんですけどまず最初IoBoundのプロセスがたくさんありますか要するに読み書きたくさんある処理ですかこれでノーだったらあんまないよもしくはCPUめっちゃ使うよ
-
これはマルチプロセスしてくださいとパフォーマンスに問題がある場合であればまあそりゃそうだと問題はここからですねAsync I.O.とマルチスレッティングの分かれ道これはI.O.が時間がかかるかI.O.処理にすごい時間がかかるかで分けろと言ってます非常に基準が曖昧で分かりづらいちょっとここでググりましたはい
-
遅いって何やねんと時間がかかるって何やねんとなるほどどの程度ならとこれどうやら普通にバックエンドAPIバックエンドAPIってDB触ったりとか対抗システムのAPI叩いたりしますけど穴ぐらいでもうすでにAsyncIOの方が早いデータベースってことなんだですね他のなんだろうなもっとメモリー
-
に対してゴニョゴニョするとかだったらもうちょっと早いのかもしれないですけどマルチスレッティングでいいかもしれないですけど通常アプリを作る上でAPIを作るんだったらもうAsyncIOの方が早いからFastAPIっていうのもあれベースのコンセプトはAsyncIOを使ってPythonでめっちゃ早いAPI作れるようになったよノードにもGoにも負けないぜっていうのがFastAPIのコンセプトなんですけどそうですそうですあれもすごいなんかAsyncIOを多用して
-
速い処理をやっていこうぜっていうなるほどフレームワークなんでというのでPython使ってバックエンド作るのであったらAsyncIO使って軽い処理というか速い処理をやっていくのがいいと思いますマルチスレッディングはIo処理が長くない場合は有効ってこと?そうですねCPUいっぱい使う場合ですねいっぱい使うというかなんだろうな
-
対抗システム使わない場合は有効かもしれないですねなるほどPythonスクリプト内で収まる範囲で
-
読み書きする程度ああそっか愛用処理が長いってことは待ち時間が多いからシングルスレッドでやっても十分平行に動かせるよっていう感じだけどそこが短い場合はあんまり待ち時間が発生しないからいっそのことリソースの競合とかを起きる可能性はあるけどたくさん動かしちゃえみたいなそういうことかそうですそうですそうですうーん
-
リソースの競合が起きやすくなるもそうですしねまさしく直感的にはマルチスレッドの方が快適そうじゃないですかビュッフェで思い浮かべちゃってるんでただビュッフェって多分待ち時間ビュッフェのキッチンって待ち時間よりも多分作業時間の方が多いんですよね割と確かにコンピューターの世界のAPIって我々が思ってるよりも待ってる時間が長いずっと待ってる
-
その状態でマルチスレッドで人々を遊ばせてリソースの競合が発生してトラブルが発生させるよりは黙って一人で作業させて適宜作業を切り替えながらやった方が早いっていうのがAsync IEOの考え方っていうので今日はマルチプロセスマルチスレッドAsync IEOの話をしてきましたけどAsync IEOも多分
-
想像ですけど他の言語でもあると思うんで多分考え方同じだと思います同じ単語を使ってるぐらいだし責任は持ちませんこの発言には持ちませんが一緒でしょうきっとなのでこれでねマルチプロセスマルチスレッドの違いもちょっと分かったと思いますしマルチプロセスは本当にメモリ領域とかリソースがごと違うキッチンも違う状態
-
キッチンの中にはそれぞれちゃんと絶対スレッドがいるでマルチスレッドは一つのプロセス一つの厨房キッチンの中で複数のスレッドが動いている状態で同じメモリーとかリソースを共有しているわけですねグローバル変数とかねそれゆえデッドロックとか競合気をつけなきゃいけないやつがマルチスレッド
-
でまあその中の文脈でAsync I/Oっていうのがありますけどそれは一人で一つの厨房で作業して適宜切り替えながらやってるからそれゆえねリソース少なくてもいいしそのリソースって言ってるのはCPUスペックとかマシンパワーとかメモリの領域とかなんだろうな使ってるメモリ量とか少ないのかなどうなんだろう1プロセスだからマルチスレッドって変わんなそうですねなんとなくマルチプロセスよりはマルチプロセスよりは少ないでしょうけどうん
-
っていう形で分かれているというのが今日伝えられたかなと思うのでなるほどこれでやや花鷹になれたかなといい感じの落とし所を見つけたツールみたいな感じですねこれをなんかOSレイヤーで解決してるってことなのかなそんなこと全部か一気通貫か多分OSから何から連携してこれができるようになってるんだなきっとどうなんだろうその話あったらちょっと待ってくださいね
-
強調型マルチタスクっていう考え方なんですよね強調型マルチタスクはプログラムが自発的にOSに一回制御を返す例えば今DBの処理待ってるから返すよーって言って開放するよー吉野に他にこれ必要な人いたら吉野にあげてねーってプログラム側から言っていくなるほどねコミュニケーションだそう多分本当にコミュニケーションですよ通信っていう意味で本当の意味でコミュニケーションですねはい
-
そういう形でやっぱだからOSというかプログラムから自発的にやって実現してるんですねそういうのも動きが違うっていうのを調べてて
-
えーってなりましたなるほど普段あんまり触れないというか本当に基本情報の1ページとかでなんだら半ページぐらいで書かれてる多分話のちょっとディープダイブっていう記事見つけて英心家用の話は多分基本情報出ないですけどでもアプリケーション開発してたらぶつかると思うんでバックエンドかなバックエンドだけだな多分待たないもんねフロントってねフロントもあるんじゃないか
-
バックエンドAPIとの通信もあったりするのかJSならあるんじゃないかJSは結構非同期処理を使うイメージあるなそうですね正直マルチプロセスよりも身近だと思っているAシンカ用の方がマルチプロセスマルチスレッドより身近だと思うので押さえておいた方が良かったと思います確かにこういうのを最初に言った方が引きがあるんですよね最後に言ってね最後に言っておこう
-
じゃあ終わりますハッシュタグひまじんプログラマーでSNSネックスでフィードバック募集してますので今日の話なんかおかしいとこあったらお手数ですがまさかりの方を置いていただけるとね投げるね投げるのはちょっと行儀悪いですけどなんならリボンとかつけちゃってねリボンつけてねおさかり置いといてもらうとありがたいですね家の前にねなんで?
-
怖いねリボン家の前にあったら怖いよまさかりってしかもまあまあでかいですよねまあなんかわかんないけどかついグーグル俺まじで絵本でしか見たことないからまさかりあとはポッドキャストの説明欄からグーグルホームで番組のお便り要望感想質問なんでもお待ちしてますのでお気軽にお願いいたします各種ポッドキャストプラットフォームのフォロー高評価もお待ちしてますのでぜひお願いいたします
-
ぜひフォローしてくださいでは終わりますまた次回バイバイ
-
あなたが落としたのはこの金のサーバーですか?へい、その金のサーバーを落としましたどうやらあなたは嘘つきのようですそう言って女神は帰っていきました欲張りの男は復旧できないサーバーの前でわんわん泣いていましたサーバーを落としたくないあなたへひまじんプログラマーの週末エンジニアリングレッスン
#328 マルチスレッド、マルチプロセス、asyncioのお話