バックグラウンド処理についてのまとめ
バックグラウンド処理の方法について調べると大量の単語が出てきたのでまとめる
- プロセス
- スレッド(Thread)
- タスク
プロセスについて
プロセスとは「実行中のプログラム(のインスタンス)」のこと
1つの実行中プログラムがプロセス
プロセス > スレッド > タスク スレッドについて
【 スレッド 】とは
スレッドは 「1つの処理の流れ(命令列)」 を実行する単位です。
通常、1つのスレッドは 1つのタスク(処理) を順番に実行します。
そのため、複数の処理を同時に行いたい場合は、
複数のスレッドを同時に実行する 「マルチスレッド」 という仕組みが使われます。
✅ マルチスレッド対応の言語(スレッドを使って並列処理ができる)
| 言語 | 特徴・備考 |
|---|---|
| Java |
Thread, ExecutorService で強力なマルチスレッド対応。OSスレッドを利用。 |
| C / C++ | POSIX Threads(pthreads)や <thread> でマルチスレッドが可能。高速だが制御が難しい。 |
| Go | 軽量スレッド「ゴルーチン」を多数並列に処理可能(実際にはスレッドプールで管理)。 |
| Rust | マルチスレッド安全性をコンパイル時に保証。所有権システムでデータ競合を防ぐ。 |
| Kotlin / Java (JVM系) | Javaと同じく Thread, Coroutine, Executor を使える。 |
| C# / .NET |
Thread, Task, async/await でマルチスレッドと非同期を両方扱える。 |
シングルスレッドの言語とは?
シングルスレッド言語では、1つのプロセスに対して基本的に1つのスレッドだけが使われ、すべての処理がその1本のスレッドで順番に実行されます。
特徴
- 並列スレッドは使わない(もしくは制限されている)
- 複雑な同期処理が不要
- 非同期タスク(イベントループ)で並行処理を実現
代表的なシングルスレッド言語
- JavaScript(Node.js)
- Python(GILのため実質シングル)
- PHP(Webリクエスト単位でプロセス実行)
✅ シングルスレッド言語(基本は1スレッドで動作)
| 言語 | 特徴・備考 |
|---|---|
| JavaScript | 完全なシングルスレッド(イベントループ+非同期I/Oで並行処理を実現)。Node.jsも同様。 |
| Python(標準実装:CPython) | GIL(Global Interpreter Lock)の影響で真のマルチスレッド不可。非同期処理やmultiprocessingが主流。 |
| Ruby | スレッド機能はあるが、GILにより実質はシングルスレッド的動作が多い。 |
| PHP | Web用途中心で、基本はシングルスレッド動作(PHP-FPMやプロセスベースの並列化が主)。 |
| Lua | 軽量スクリプト言語。基本はシングルスレッド。C言語との連携でスレッド制御可能だが特殊。 |
シングルスレッドで複数の処理を同時に行う方法
✅ 背景
シングルスレッドの言語(例:JavaScript, Python など)は、
1つのスレッド(実行の流れ)だけで処理を行うため、
本来は「複数の処理を同時に実行する」ことはできません。
しかし、非同期処理やイベントループを利用することで、
あたかも複数の処理を同時に行っているように見せることが可能です。
非同期処理(並行(へいこう)処理)
- 疑似的 に 複数処理 を同時に行っているように見せる
| 特徴/方式 | マルチプロセス | マルチスレッド | 非同期タスク |
|---|---|---|---|
| 並列処理 | ◎(真の並列) | ◎(真の並列) | △(擬似並列) |
| メモリ分離 | ◎ | ×(共有) | ◯(基本共有) |
| 安定性 | ◎ | △ | ◎ |
| 実装難易度 | △(プロセス制御) | △~×(同期の難しさ) | ◯(非同期制御) |
| 代表言語 | Python, Node.js, Erlang | Java, C++, Go | JS, Python(asyncio) |
1. 用語の違い(修正版)
| 項目 | マルチプロセス | マルチスレッド | 非同期タスク(マルチタスクの一形態) |
|---|---|---|---|
| 処理単位 | プロセス(完全に独立) | スレッド(プロセス内の実行単位) | タスク(スレッド内の非同期処理単位) |
| メモリ空間 | 分離(プロセスごとに独立) | 共有(プロセス内の全スレッドで共通) | 共有(スレッド内で切り替え) |
| 並列性 | ◯(OSが複数プロセスを並列実行) | ◯(OSが複数スレッドを並列実行) | △(実際は並行。非同期的に切り替え) |
| 安定性 | ◎(クラッシュの影響が波及しにくい) | △(メモリ共有によるバグで影響を受けやすい) | ◎(1スレッド内なら安全。軽量で制御しやすい) |
| 主な用途 | 高負荷処理の分離、障害耐性設計 | 並列演算、UI+バックグラウンド処理 | Webアプリ、非同期I/O、軽量な待機処理 |
2. バックグラウンド処理との関係
| 方式 | バックグラウンド処理の方法 | 代表的な用途 |
|---|---|---|
| マルチスレッド | メインスレッドとは別に処理 | UI非同期処理、通信 |
| マルチプロセス | 別プロセスとして処理 | 並列処理、重い計算 |
| 非同期タスク | イベントループ内で切り替え | I/O待ち、API呼び出し |
| ジョブ/キュー | キューに登録して非同期処理 | メール送信、画像変換 |
3. 言語との関係
| 言語 | 処理方式 | 備考 |
|---|---|---|
| Python | マルチプロセス、asyncio | GIL制限のためプロセス優位 |
| Java | マルチスレッド中心 | Thread, ExecutorServiceなど |
| JavaScript | 非同期タスク中心 | イベントループ/Promiseで並行処理 |
| Go | ゴルーチン(軽量スレッド) | マルチスレッド的に扱える |
4. 結論
-
マルチプロセス:完全分離の処理。安全性高いが通信コストあり
-
マルチスレッド:高速処理が可能だが同期制御が複雑
-
非同期タスク:軽量で簡易なバックグラウンド処理に向く
-
バックグラウンド処理は、上記いずれかで実現可能
┌─────────────┐ │ マルチタスク │ └────┬────────┘ │ ├─ 非同期タスク(async/await など) ├─ マルチスレッド(スレッド単位のタスク切り替え) └─ マルチプロセス(プロセス単位のタスク実行)
✅ 並行処理・並列処理の主な種類一覧
| 種類 | 説明 | 制御単位 | 主な特徴・備考 |
|---|---|---|---|
| プロセス(Process) | OS上の独立した実行単位 | プロセス | メモリ空間が完全に分離。安定性◎。重め。 |
| スレッド(Thread) | プロセス内での並列実行単位 | スレッド | メモリ共有で高速。同期処理が必要。 |
| 非同期(Async) | 処理を待たずに進行(協調型) | タスク(コルーチンなど) | 軽量でI/O待ちに強い。1スレッドでも複数処理が可能。 |
| コルーチン(Coroutine) | 非同期の一種。手動で制御を譲る | タスク |
async/await の背後で使われる。 |
| イベントループ(Event Loop) | 非同期処理を順番に処理するループ | タスク | JavaScript、Pythonなどで使用。 |
| スレッドプール(Thread Pool) | スレッドを再利用する仕組み | スレッド群 | コストを抑えてスレッドを管理。 |
| ゴルーチン(Goroutine) | Go言語の軽量スレッド | タスク(軽量スレッド) | スレッドより高速・多数起動可能。 |
並行処理(Concurrency)
├── マルチプロセス(プロセス単位)
├── マルチスレッド(スレッド単位)
└── 非同期処理(async/await)
├── イベントループ
└── コルーチン(coroutine)✅ 各言語におけるスレッド・非同期処理の対応一覧
| 言語 | スレッド処理 | 非同期処理 (async/await) |
キュー/タスクの扱い | 備考 |
|---|---|---|---|---|
| PHP | プロセスベース中心(pcntl, pthreads ※CLI限定) |
Laravelなどでジョブキュー/非同期タスク処理 | ワーカー・ジョブとして非同期処理 | Web用でスレッド非推奨。Queue処理が主流 |
| SwiftUI(Swift) | GCD(Grand Central Dispatch)で非同期スレッド制御 |
async/await(Swift 5.5~) |
DispatchQueue, Task, Actor
|
モダンな非同期タスク指向設計 |
| Python |
threading, multiprocessing
|
asyncio, await
|
asyncio.Queue, celery
|
GILの制限あり。CPU処理はプロセス推奨 |
| JavaScript | スレッド不可(Web Worker等で回避) |
async/await, Promise
|
イベントループベース、タスクキュー | シングルスレッドで非同期に特化 |
| Java |
Thread, Executor, Future
|
CompletableFuture, async frameworks |
BlockingQueue, ForkJoinPool
|
高度なスレッド制御が可能 |
| Go | 非公開のスレッド + goroutine
|
ゴルーチンは同期・非同期両対応 |
channel, worker pool, queue構造 |
並行処理が非常に得意 |
✅ 実装例(言語別)
▶ PHP(Laravelでの非同期ジョブ処理)
// ジョブクラスを作成
php artisan make:job SendEmail
// ジョブ内で処理を記述
public function handle()
{
Mail::to($this->user)->send(new WelcomeMail());
}
// コントローラーなどでキューへ送信
SendEmail::dispatch($user);
▶ SwiftUI(Swift 5.5+ 非同期+キュー制御)
✅ 非同期タスク(async/await)
import SwiftUI
struct ContentView: View {
var body: some View {
Button("Fetch Data") {
Task {
await fetchData()
}
}
}
func fetchData() async {
// 非同期でデータを取得
let data = try? await URLSession.shared.data(from: URL(string: "https://example.com")!)
print(data ?? "エラー")
}
}
| 分類 | 対象 | 特徴 |
|---|---|---|
| スレッド系 |
Thread, Task, Goroutine
|
並列実行。高速だが複雑(同期制御が必要) |
| 非同期系 |
async/await, Promise, Coroutine
|
並行実行。I/Oに強い。軽量。 |
| プロセス系 |
multiprocessing, fork
|
独立性・安定性が高い。通信は重め。 |
自分が混乱したポイント
同期処理なのに結果を待ってくれない
❓ 質問:同期関数は結果を待たずに進むか?
✅ 答え:いいえ、常に結果(関数の処理完了)を待ってから次に進みます。
「同期関数が結果を待たずに進む」と感じるのは イベント駆動型プログラミング である可能性がある
イベント駆動型プログラミングとは
現在のアプリ開発(Web・モバイル・GUIアプリ)では、ほとんどの開発環境・フレームワークが イベント駆動型 です。
✅ 結論
UIを持つアプリ(ボタン、入力欄、スクロール、通信など)が関係する限り、イベント駆動型が「標準的な設計」です。
| 種類 | 動作の特徴 | 次の処理に進む条件 |
|---|---|---|
| 同期関数 | 処理が終わるまで待機 | 関数が完了してから |
| 非同期関数 | 処理を途中で中断可能 |
await しなければすぐ次に進む |
✅ 概要
イベント駆動型(Event-Driven)とは、イベントの発生をトリガーにして処理を実行する設計スタイルです。
ユーザー操作(クリック、入力)、非同期完了、通知などに応じてアプリケーションが反応します。
✅ 特徴
| 特徴 | 説明 |
|---|---|
| 非同期性 | 処理はイベント発生時に非同期で実行され、ブロッキングしない |
| 柔軟性 | ユーザーの操作や外部の応答に応じて動的に処理を切り替えられる |
| UI向け | GUI・Web・モバイルアプリなど、ユーザーの操作を扱うアプリに最適 |
| 高応答性 | イベントを待ちつつ、アプリ自体は固まらずに動作し続ける |
✅ 実例(Vue.jsの場合)
<template>
<button @click="doSomething">実行</button>
</template>
<script>
export default {
methods: {
doSomething() {
console.log("クリックされました");
}
}
}
</script>
-
@clickはイベントハンドラ -
doSomething()はイベントが発生したときに呼ばれる関数
✅ 処理の流れ(VueなどのUIフレームワーク)
[ユーザー操作 or 非同期イベント]
↓
[イベント発生]
↓
[登録された関数を非同期で実行]
↓
[状態変更 → リアクティブシステムがUI更新]
✅ 主なイベントドリブン環境
| プラットフォーム | 開発環境/フレームワーク | 例 |
|---|---|---|
| Web | Vue.js, React, Angular | クリック、スクロール、通信完了など |
| モバイル | SwiftUI, Android | タップ、非同期API、通知 |
| デスクトップ | Electron, WPF, Qt | ボタン操作、ファイル読み書き完了など |
| ゲーム | Unity, Unreal Engine | プレイヤー操作、物理演算イベントなど |
✅ イベント駆動型のメリットと注意点
✅ メリット
- 非同期に対応しやすく、UIが固まらない
- 複雑なユーザー操作にも柔軟に対応できる
- 処理をコンポーネント単位で分離しやすい
⚠️ 注意点
- 処理の順序が見えにくくなり、デバッグが難しくなることがある
- すべての処理が「イベント依存」になるため、全体の流れが把握しづらい場合も
✅ まとめ
イベント駆動型 のコードは、処理が重い場合、結果を待ってくれないから
非同期にして awaitで結果を待つように書かないと結果をスルーしてそのまま動いてしまう
- イベント駆動型は、ユーザー操作や外部イベントをトリガーにして処理を進める設計。
- 非同期処理と密接に関係しており、UIアプリ開発においては事実上の標準アーキテクチャ。
- Vue や React、SwiftUI、Electron など、現代の主要なアプリ開発環境ではすべてイベント駆動型が採用されている。
JavaScriptの await と .then() について
await と .then() の比較まとめ
✅ 結論
-
awaitと.then()は 機能は同じ(Promise の完了を待って値を取得) - 違うのは 書き方(構文)と見え方(同期的/非同期的)
🔸 共通点
- どちらも Promise を扱う
- 結果が返るまで待機し、成功時は値を受け取る、失敗時はエラーになる
🔸 使用例の比較
.then() を使う場合
fetchData().then(data => {
console.log("then版:", data);
});
await を使う場合(async 関数内で)
async function run() {
const data = await fetchData();
console.log("await版:", data);
}
run();
🔍 違いの比較表
| 比較項目 | .then() |
await |
|---|---|---|
| 使用できる場所 | 通常の関数内でも使用可 |
async 関数の中でのみ使用可能 |
| 実行の流れ | 非同期的に処理が分かれる | 同期的に見えるが内部は非同期 |
| ネスト構造 | ネストが深くなりやすい | フラットで読みやすい |
| エラーハンドリング |
.catch() を使用 |
try { ... } catch { ... } を使用 |
| 並列処理 | 比較的書きやすい |
Promise.all() 等を併用する必要あり |
🧪 実行順の違い(例)
.then() の場合
console.log("処理開始");
fetchData().then(data => {
console.log(data);
});
console.log("処理終了");
結果:
処理開始
処理終了
データ取得完了(2秒後)
await の場合
async function main() {
console.log("処理開始");
const data = await fetchData();
console.log(data);
console.log("処理終了");
}
main();
結果:
処理開始
(2秒待つ)
データ取得完了
処理終了
✅ 実務での使い分け
- 簡単な処理や短い関数 →
.then()もアリ - 複雑な処理・順番が重要・見通しを良くしたい →
await推奨
💡 ヒント
-
awaitは.then()の糖衣構文(syntactic sugar) - 実行順を制御したいなら
await - 並列処理を効率よく書きたいなら
Promise.all+await



