m07-concurrency
並行処理や非同期処理におけるスレッド間でのデータの受け渡し、排他制御、アトミック操作などに関するエラーや問題解決を支援し、デッドロックや競合状態を回避するためのコード修正を提案するSkill。
📜 元の英語説明(参考)
CRITICAL: Use for concurrency/async. Triggers: E0277 Send Sync, cannot be sent between threads, thread, spawn, channel, mpsc, Mutex, RwLock, Atomic, async, await, Future, tokio, deadlock, race condition, 并发, 线程, 异步, 死锁
🇯🇵 日本人クリエイター向け解説
並行処理や非同期処理におけるスレッド間でのデータの受け渡し、排他制御、アトミック操作などに関するエラーや問題解決を支援し、デッドロックや競合状態を回避するためのコード修正を提案するSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o m07-concurrency.zip https://jpskill.com/download/9266.zip && unzip -o m07-concurrency.zip && rm m07-concurrency.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/9266.zip -OutFile "$d\m07-concurrency.zip"; Expand-Archive "$d\m07-concurrency.zip" -DestinationPath $d -Force; ri "$d\m07-concurrency.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
m07-concurrency.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
m07-concurrencyフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
並行性
レイヤー1: 言語の仕組み
中核となる質問
これは CPU バウンドですか、それとも I/O バウンドですか? そして、共有モデルは何ですか?
並行処理プリミティブを選択する前に:
- ワークロードの種類は何ですか?
- どのデータを共有する必要がありますか?
- スレッドセーフの要件は何ですか?
エラー → 設計に関する質問
| エラー | 単に言うのではなく | 代わりに尋ねる |
|---|---|---|
| E0277 Send | 「Send バウンドを追加する」 | この型はスレッドをまたぐべきですか? |
| E0277 Sync | 「Mutex でラップする」 | 共有アクセスは本当に必要ですか? |
| Future not Send | 「spawn_local を使用する」 | async は正しい選択ですか? |
| デッドロック | 「ロックの順序を変更する」 | ロックの設計は正しいですか? |
思考を促すプロンプト
並行処理を追加する前に:
-
ワークロードは何ですか?
- CPU バウンド → スレッド (std::thread, rayon)
- I/O バウンド → async (tokio, async-std)
- 混合 → ハイブリッドアプローチ
-
共有モデルは何ですか?
- 共有なし → メッセージパッシング (channels)
- イミュータブルな共有 → Arc<T>
- ミュータブルな共有 → Arc<Mutex<T>> または Arc<RwLock<T>>
-
Send/Sync の要件は何ですか?
- スレッド間の所有権の移動 → Send
- スレッド間の参照の共有 → Sync
- シングルスレッド async → spawn_local
トレースアップ ↑ (必須)
重要: 単にエラーを修正するだけではありません。トレースアップして、ドメインの制約を見つけてください。
ドメイン検出テーブル
| コンテキストキーワード | ロードするドメインスキル | 主要な制約 |
|---|---|---|
| Web API, HTTP, axum, actix, handler | domain-web | ハンドラーは任意のスレッドで実行される |
| 交易, 支付, trading, payment | domain-fintech | 監査 + スレッドセーフ |
| gRPC, kubernetes, microservice | domain-cloud-native | 分散トレーシング |
| CLI, terminal, clap | domain-cli | 通常、シングルスレッドで OK |
例: Web API + Rc エラー
"Rc cannot be sent between threads" in Web API context
↑ DETECT: "Web API" → Load domain-web
↑ FIND: domain-web says "Shared state must be thread-safe"
↑ FIND: domain-web says "Rc in state" is Common Mistake
↓ DESIGN: Use Arc<T> with State extractor
↓ IMPL: axum::extract::State<Arc<AppConfig>>
一般的なトレース
"Send not satisfied for my type"
↑ Ask: What domain is this? Load domain-* skill
↑ Ask: Does this type need to cross thread boundaries?
↑ Check: m09-domain (is the data model correct?)
| 状況 | トレース先 | 質問 |
|---|---|---|
| Web での Send/Sync | domain-web | ステート管理パターンは何ですか? |
| CLI での Send/Sync | domain-cli | マルチスレッドは本当に必要ですか? |
| Mutex vs channels | m09-domain | 共有状態ですか、それともメッセージパッシングですか? |
| Async vs threads | m10-performance | ワークロードプロファイルは何ですか? |
トレースダウン ↓
設計から実装へ:
"Need parallelism for CPU work"
↓ Use: std::thread or rayon
"Need concurrency for I/O"
↓ Use: async/await with tokio
"Need to share immutable data across threads"
↓ Use: Arc<T>
"Need to share mutable data across threads"
↓ Use: Arc<Mutex<T>> or Arc<RwLock<T>>
↓ Or: channels for message passing
"Need simple atomic operations"
↓ Use: AtomicBool, AtomicUsize, etc.
Send/Sync マーカー
| マーカー | 意味 | 例 |
|---|---|---|
Send |
スレッド間で所有権を移動できる | ほとんどの型 |
Sync |
スレッド間で参照を共有できる | Arc<T> |
!Send |
1つのスレッドにとどまる必要がある | Rc<T> |
!Sync |
スレッド間で共有参照を持てない | RefCell<T> |
クイックリファレンス
| パターン | スレッドセーフ | ブロッキング | 使用する場面 |
|---|---|---|---|
std::thread |
はい | はい | CPU バウンドの並列処理 |
async/await |
はい | いいえ | I/O バウンドの並行処理 |
Mutex<T> |
はい | はい | 共有ミュータブルステート |
RwLock<T> |
はい | はい | 読み込みが多い共有ステート |
mpsc::channel |
はい | オプション | メッセージパッシング |
Arc<Mutex<T>> |
はい | はい | スレッド間で共有されるミュータブル |
意思決定フローチャート
What type of work?
├─ CPU-bound → std::thread or rayon
├─ I/O-bound → async/await
└─ Mixed → hybrid (spawn_blocking)
Need to share data?
├─ No → message passing (channels)
├─ Immutable → Arc<T>
└─ Mutable →
├─ Read-heavy → Arc<RwLock<T>>
└─ Write-heavy → Arc<Mutex<T>>
└─ Simple counter → AtomicUsize
Async context?
├─ Type is Send → tokio::spawn
├─ Type is !Send → spawn_local
└─ Blocking code → spawn_blocking
よくあるエラー
| エラー | 原因 | 修正 |
|---|---|---|
E0277 Send not satisfied |
async で Non-Send | Arc を使用するか、spawn_local を使用する |
E0277 Sync not satisfied |
Non-Sync が共有されている | Mutex でラップする |
| デッドロック | ロックの順序 | 一貫したロック順序 |
future is not Send |
await をまたいで Non-Send | await の前にドロップする |
MutexGuard across await |
中断中にガードが保持されている | ガードを適切にスコープする |
アンチパターン
| アンチパターン | なぜ悪いのか | より良い方法 |
|---|---|---|
| Arc<Mutex<T>> がどこにでもある | 競合、複雑さ | メッセージパッシング |
| async で thread::sleep | エグゼキュータをブロックする | tokio::time::sleep |
| await をまたいでロックを保持する | 他のタスクをブロックする | ロックを厳密にスコープする |
| デッドロックのリスクを無視する | デバッグが難しい | ロックの順序、try_lock |
Async 固有のパターン
Await をまたいで MutexGuard を避ける
// Bad: guard held across await
let guard = mutex.lock().await;
do_async().await; // guard still held!
// Good: scope the lock
{
let guard = mutex.lock().await;
// use guard
} // guard dropped
do_async().await;
Async での Non-Send 型
// Rc is !Send, can't cross await in spawned task
// Option 1: use Arc instead
// Option 2: use spawn_local (single-thread runtime)
// Option 3: ensure Rc is dropped before .await
関連スキル
| いつ | 参照 |
|---|---|
| スマートポインタの選択 | m02-resource |
| 内部可変性 | m03-mutability |
| パフォーマンスチューニング | m10-performance |
| ドメインの並行性のニーズ | domain-* |
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
Concurrency
Layer 1: Language Mechanics
Core Question
Is this CPU-bound or I/O-bound, and what's the sharing model?
Before choosing concurrency primitives:
- What's the workload type?
- What data needs to be shared?
- What's the thread safety requirement?
Error → Design Question
| Error | Don't Just Say | Ask Instead |
|---|---|---|
| E0277 Send | "Add Send bound" | Should this type cross threads? |
| E0277 Sync | "Wrap in Mutex" | Is shared access really needed? |
| Future not Send | "Use spawn_local" | Is async the right choice? |
| Deadlock | "Reorder locks" | Is the locking design correct? |
Thinking Prompt
Before adding concurrency:
-
What's the workload?
- CPU-bound → threads (std::thread, rayon)
- I/O-bound → async (tokio, async-std)
- Mixed → hybrid approach
-
What's the sharing model?
- No sharing → message passing (channels)
- Immutable sharing → Arc<T>
- Mutable sharing → Arc<Mutex<T>> or Arc<RwLock<T>>
-
What are the Send/Sync requirements?
- Cross-thread ownership → Send
- Cross-thread references → Sync
- Single-thread async → spawn_local
Trace Up ↑ (MANDATORY)
CRITICAL: Don't just fix the error. Trace UP to find domain constraints.
Domain Detection Table
| Context Keywords | Load Domain Skill | Key Constraint |
|---|---|---|
| Web API, HTTP, axum, actix, handler | domain-web | Handlers run on any thread |
| 交易, 支付, trading, payment | domain-fintech | Audit + thread safety |
| gRPC, kubernetes, microservice | domain-cloud-native | Distributed tracing |
| CLI, terminal, clap | domain-cli | Usually single-thread OK |
Example: Web API + Rc Error
"Rc cannot be sent between threads" in Web API context
↑ DETECT: "Web API" → Load domain-web
↑ FIND: domain-web says "Shared state must be thread-safe"
↑ FIND: domain-web says "Rc in state" is Common Mistake
↓ DESIGN: Use Arc<T> with State extractor
↓ IMPL: axum::extract::State<Arc<AppConfig>>
Generic Trace
"Send not satisfied for my type"
↑ Ask: What domain is this? Load domain-* skill
↑ Ask: Does this type need to cross thread boundaries?
↑ Check: m09-domain (is the data model correct?)
| Situation | Trace To | Question |
|---|---|---|
| Send/Sync in Web | domain-web | What's the state management pattern? |
| Send/Sync in CLI | domain-cli | Is multi-thread really needed? |
| Mutex vs channels | m09-domain | Shared state or message passing? |
| Async vs threads | m10-performance | What's the workload profile? |
Trace Down ↓
From design to implementation:
"Need parallelism for CPU work"
↓ Use: std::thread or rayon
"Need concurrency for I/O"
↓ Use: async/await with tokio
"Need to share immutable data across threads"
↓ Use: Arc<T>
"Need to share mutable data across threads"
↓ Use: Arc<Mutex<T>> or Arc<RwLock<T>>
↓ Or: channels for message passing
"Need simple atomic operations"
↓ Use: AtomicBool, AtomicUsize, etc.
Send/Sync Markers
| Marker | Meaning | Example |
|---|---|---|
Send |
Can transfer ownership between threads | Most types |
Sync |
Can share references between threads | Arc<T> |
!Send |
Must stay on one thread | Rc<T> |
!Sync |
No shared refs across threads | RefCell<T> |
Quick Reference
| Pattern | Thread-Safe | Blocking | Use When |
|---|---|---|---|
std::thread |
Yes | Yes | CPU-bound parallelism |
async/await |
Yes | No | I/O-bound concurrency |
Mutex<T> |
Yes | Yes | Shared mutable state |
RwLock<T> |
Yes | Yes | Read-heavy shared state |
mpsc::channel |
Yes | Optional | Message passing |
Arc<Mutex<T>> |
Yes | Yes | Shared mutable across threads |
Decision Flowchart
What type of work?
├─ CPU-bound → std::thread or rayon
├─ I/O-bound → async/await
└─ Mixed → hybrid (spawn_blocking)
Need to share data?
├─ No → message passing (channels)
├─ Immutable → Arc<T>
└─ Mutable →
├─ Read-heavy → Arc<RwLock<T>>
└─ Write-heavy → Arc<Mutex<T>>
└─ Simple counter → AtomicUsize
Async context?
├─ Type is Send → tokio::spawn
├─ Type is !Send → spawn_local
└─ Blocking code → spawn_blocking
Common Errors
| Error | Cause | Fix |
|---|---|---|
E0277 Send not satisfied |
Non-Send in async | Use Arc or spawn_local |
E0277 Sync not satisfied |
Non-Sync shared | Wrap with Mutex |
| Deadlock | Lock ordering | Consistent lock order |
future is not Send |
Non-Send across await | Drop before await |
MutexGuard across await |
Guard held during suspend | Scope guard properly |
Anti-Patterns
| Anti-Pattern | Why Bad | Better |
|---|---|---|
| Arc<Mutex<T>> everywhere | Contention, complexity | Message passing |
| thread::sleep in async | Blocks executor | tokio::time::sleep |
| Holding locks across await | Blocks other tasks | Scope locks tightly |
| Ignoring deadlock risk | Hard to debug | Lock ordering, try_lock |
Async-Specific Patterns
Avoid MutexGuard Across Await
// Bad: guard held across await
let guard = mutex.lock().await;
do_async().await; // guard still held!
// Good: scope the lock
{
let guard = mutex.lock().await;
// use guard
} // guard dropped
do_async().await;
Non-Send Types in Async
// Rc is !Send, can't cross await in spawned task
// Option 1: use Arc instead
// Option 2: use spawn_local (single-thread runtime)
// Option 3: ensure Rc is dropped before .await
Related Skills
| When | See |
|---|---|
| Smart pointer choice | m02-resource |
| Interior mutability | m03-mutability |
| Performance tuning | m10-performance |
| Domain concurrency needs | domain-* |