概要
「並行処理」「並列処理」「同期処理・非同期処理」という言葉が自分の中で紛らわしかったので勉強したことをまとめてみます。
それぞれの言葉の意味
- 並行処理:複数の処理を1つの主体が切り替えながらこなすこと
- 並列処理:複数の処理を複数の主体で同時にこなすこと
- 同期処理:複数の処理をこなす際、ある処理が別の処理の終了を待つような処理
- 非同期処理:複数の処理をこなす際、ある処理は別の処理の終了を待たないような処理
それぞれの言葉の目的
- 並行処理:処理を「同時に進行させる」ことが目的
- 並列処理:処理を「速くこなすこと」が目的
- 同期処理・非同期処理:別の処理を「待つ必要があるか・ないか」を語ることが目的
それぞれは語られる場所が異なるため、並べて語ることができない概念であると私は考えています。(参考:並行処理、並列処理のあれこれ)
それぞれの言葉の説明
並行処理
並行処理 とは、複数の処理を、重複する時間枠内で同時に進行させることを意味します。- リアクティブの実践、単元 4: 同時並行性、並列処理、非同期
「並行処理」が語られるとき、大抵は「一つの主体が複数の動作を『切り替えながら』行うこと」を意味しています。このとき重要なのは「複数のプロセスが実行状態である」ということ。つまり「複数のプロセスが同時にして実行状態にある様」を「並行」と呼んでいるのであり、この言葉が使われる際の処理の主体は常に一つです。また、ある一点において実行されている処理も常に一つとなります。
上記引用元の記事では並行処理を「一人のディーラーがトランプを二組の山に分ける様」で例えています。ディーラーは「山を作る」という動作を「二つ同時」にやっていますが、それはあくまで二つの作業を切り替えながらやっているにすぎません。これが並行的であるということ。
コンピュータで言うならば、私たちはあるファイルをダウンロードしながら、方やyoutubeで動画を視聴することができます。これはCPUが複数のプロセスを高速で切り替えながら実行しているためになせる業です。このとき「複数のプロセスが同時に進行」しています (参考:【小ネタ】並列処理とは何か?そして並列処理と並行処理の違いとは?)。
元々はCPUが1Coreで動作していた時代に、複数のプロセスを1Coreで切り替えながらやっていたことから生まれた言葉であると考えられます。ですので「並列処理」という言葉より先に生まれた言葉であると考えられます。(参考:並行処理から並列処理へ)
並列処理
並列処理 とは、複数のプロセスが同時に進行していくことを意味します。- リアクティブの実践、単元 4: 同時並行性、並列処理、非同期
「並列処理」が語られるとき、それは「複数の主体が『同時』に複数の処理をこなすこと」を意味しています。つまり「ある一点において文字通り複数の処理が同時進行している様」を「並列」と呼んでいます。逆に並列処理は複数の処理主体がいなければ実行することはできないことになります。
CPUのcoreが1つだけの場合、並列処理というのはありえません。- 並行処理、並列処理のあれこれ
先ほどの引用元では並列処理を「複数のディーラがそれぞれのトランプを2組の山に分ける様」で例えています。複数のディーラーで処理を行うわけですから、当然ある一点においてそれぞれの「トランプを分ける」作業は同時に進んでいます。これが並列的であるということ。
同じマルチスレッドプロセスが共有メモリー方式のマルチプロセッサ上で動作する場合は、プロセス中の各スレッドが別のプロセッサ上で同時に走行するため、プロセスの実行状態は並列的になります。- 並行性と並列性
コンピュータにおいては、この引用のような場合が並列処理です。ある処理を複数の処理主体で行うため、当然1つの主体で行うよりも処理時間が「速く」なります。これが並列処理の要点であると考えています。(参考:並列処理概論)
同期処理・非同期処理
- 同期処理では、あるタスクが実行している間、他のタスクの処理は中断される方式である。
- 非同期処理は、あるタスクが実行をしている際に、他のタスクが別の処理を実行できる方式である。
I-26-2. 非同期処理と同期処理の実装パターンと特徴
「同期処理」処理が語られるとき、それは「ある処理が他の処理の終了を待たなければならない」ことを意味しています。「非同期処理」は「他の処理の終了を待たなくてよい」ことを意味しています。
例えば「カレーライス調理」において、「盛り付け」は必ず「ご飯とカレーの調理」の終了を待たなければなりません。これは「盛り付け」が「ご飯とカレーの調理」と同期をとならなければならないことを意味しています。
しかし、「ご飯の調理」の終了を待たずして「カレーの調理」を始めることはできます(ご飯の炊きあがりを待つ間にカレーを調理する)。これは「ご飯の調理」と「カレーの調理」は非同期でよいことを意味しています。
コンピュータの世界だと、例えばJavaで「HashMapを使用する処理」を複数スレッドで行うなら、それらの処理は「同期処理」でないといけません(HashMapは複数スレッドから同時に値が変更されたとき、どの値を返すかは保証できないため)。
しかし、例えば「顧客情報の作成処理」を複数スレッドで行うとき、単一の作成処理は別の作成処理に影響を及ぼさないために「非同期処理」で構わないことがあります。
つまり「同期・非同期処理」が語られるときは「ある処理が他の処理の終了を待たなければならないなどうか」が語られていると私は考えています。(参考:同期)
それぞれの言葉の比較
以前疑問に思っていたことについてまとめてみます。
同期処理=並行処理?
結論:Noである
- 「並行処理」において「同期処理をしなければならない(同期をとらなければならない)」場合がある。
- 「同期処理」を「並行的」に処理することはできない(処理の順番が重要だから)。
同期処理=並列処理?
結論:Noである
- 「並列処理」において「同期処理をしなければならない(同期をとらなければならない)」場合がある。
- 「同期処理」を「並列的」に処理することはできない(処理の順番が重要だから)。
非同期処理=並行処理?
結論:Noである
- Javaの非同期処理はマルチスレッドで「並列的」に処理されることがある。
非同期処理=並列処理?
結論:Noである
- JavaScriptの非同期処理は「並行的」に処理される(参考:JavaScriptの非同期処理を並列処理と勘違いしていませんか?)
並行処理=並列処理?
結論:Noである
並行・並列プログラミングと並べて語られるのはなぜ?
結論:両者の目的が同じだから
- どちらも「複数スレッドによる同一リソースへのアクセス」をする場合は「競合状態」が生じる可能性があるのでプログラムへの考慮が必要(参考:できる!並列・並行プログラミング)
まとめ
「並行処理」「並列処理」「同期処理・非同期処理」はそれぞれが違う目的で使われる概念であるため、比較しづらいことが分かりました。
「並列処理の中の同期処理」のようにそれぞれが同時に存在する場合もあるし、それぞれのうちのどれか一つにしか該当しない処理があるのも、私がそれぞれを比較できないと考えている理由でもあります。
しかし、それぞれの言葉自体がよく耳にするものなので、定義をはっきりさせておく必要があると感じています。