tokio
Tokioはシステムの非同期性能の最適化を行うRustの非同期ランタイムで、RustのAsync エコシステムの大部分を支えています。あなたはTokioのタスクスケジューラ、非同期I/Oプリミティブ、チャネル、タイマー、同期ユーティリティを活用して、開発者が高性能なネットワークアプリケーション、並行処理サービス、I/O集約型システムを構築するのをサポートします。最小限のメモリオーバーヘッドで数百万の並行接続を処理できます。
description の原文を見る
You are an expert in Tokio, the asynchronous runtime for Rust that powers most of the Rust async ecosystem. You help developers build high-performance network applications, concurrent services, and I/O-bound systems using Tokio's task scheduler, async I/O primitives, channels, timers, and synchronization utilities — handling millions of concurrent connections with minimal memory overhead.
SKILL.md 本文
Tokio — Rust用の非同期ランタイム
Rustの非同期ランタイムである Tokio のエキスパートです。Rust非同期エコシステムの大部分を支える Tokio により、Tokioのタスクスケジューラー、非同期I/Oプリミティブ、チャネル、タイマー、同期ユーティリティを使用して、高性能なネットワークアプリケーション、並行サービス、I/Oバウンドシステムをビルドする開発者をサポートします。最小限のメモリオーバーヘッドで数百万の並行接続を処理できます。
コア機能
非同期タスク
use tokio::time::{sleep, Duration};
use tokio::task;
#[tokio::main]
async fn main() {
// Spawn concurrent tasks
let handle1 = task::spawn(async {
sleep(Duration::from_secs(1)).await;
"Task 1 done"
});
let handle2 = task::spawn(async {
sleep(Duration::from_millis(500)).await;
"Task 2 done"
});
// Await both
let (r1, r2) = tokio::join!(handle1, handle2);
println!("{}, {}", r1.unwrap(), r2.unwrap());
// Select first to complete
tokio::select! {
val = async { sleep(Duration::from_secs(1)).await; "slow" } => {
println!("Got: {val}");
}
val = async { sleep(Duration::from_millis(100)).await; "fast" } => {
println!("Got: {val}");
}
}
// Spawn blocking work (CPU-intensive) on dedicated thread pool
let result = task::spawn_blocking(|| {
heavy_computation() // Won't block async runtime
}).await.unwrap();
}
チャネル
use tokio::sync::{mpsc, broadcast, oneshot, watch};
// mpsc: Multiple producers, single consumer
let (tx, mut rx) = mpsc::channel::<String>(100); // Buffer size 100
let tx2 = tx.clone();
task::spawn(async move { tx.send("hello".into()).await.unwrap(); });
task::spawn(async move { tx2.send("world".into()).await.unwrap(); });
while let Some(msg) = rx.recv().await {
println!("Got: {msg}");
}
// broadcast: Multiple producers, multiple consumers
let (tx, _) = broadcast::channel::<String>(100);
let mut rx1 = tx.subscribe();
let mut rx2 = tx.subscribe();
tx.send("event".into()).unwrap();
// Both rx1 and rx2 receive "event"
// oneshot: Single value, single use (request-response)
let (tx, rx) = oneshot::channel::<String>();
tx.send("response".into()).unwrap();
let val = rx.await.unwrap();
// watch: Single value that can be updated and observed
let (tx, mut rx) = watch::channel("initial".to_string());
tx.send("updated".into()).unwrap();
rx.changed().await.unwrap();
TCPサーバー
use tokio::net::TcpListener;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
#[tokio::main]
async fn main() -> std::io::Result<()> {
let listener = TcpListener::bind("0.0.0.0:8080").await?;
loop {
let (mut socket, addr) = listener.accept().await?;
println!("New connection from {addr}");
tokio::spawn(async move {
let mut buf = vec![0u8; 1024];
loop {
let n = match socket.read(&mut buf).await {
Ok(0) => return, // Connection closed
Ok(n) => n,
Err(e) => { eprintln!("Read error: {e}"); return; }
};
if socket.write_all(&buf[..n]).await.is_err() {
return; // Write error
}
}
});
}
}
同期プリミティブ
use tokio::sync::{Mutex, RwLock, Semaphore};
use std::sync::Arc;
// Async Mutex (yields while waiting, doesn't block thread)
let data = Arc::new(Mutex::new(vec![1, 2, 3]));
let data_clone = data.clone();
tokio::spawn(async move {
let mut lock = data_clone.lock().await;
lock.push(4);
});
// RwLock: Multiple readers OR single writer
let cache = Arc::new(RwLock::new(HashMap::new()));
let read = cache.read().await; // Non-exclusive
let mut write = cache.write().await; // Exclusive
// Semaphore: Limit concurrency
let semaphore = Arc::new(Semaphore::new(10)); // Max 10 concurrent
let permit = semaphore.acquire().await.unwrap();
// ... do work ...
drop(permit); // Release
インストール
[dependencies]
tokio = { version = "1", features = ["full"] }
# または選別して: features = ["rt-multi-thread", "macros", "net", "io-util", "time", "sync"]
ベストプラクティス
- ランタイムをブロックしない — CPU集約的または同期I/Oには
spawn_blockingを使用します。非同期スレッドをブロックすると、他のタスクが飢餓状態になります - 通信にはチャネルを使用 — ワークキューには mpsc、イベントには broadcast、設定更新には watch を使用します
- レースには Select を使用 —
tokio::select!は最初に完了したフューチャーを選びます。タイムアウトとキャンセルに最適です - 非同期Mutex vs 標準Mutex —
.awaitの間ロックを保持する場合はtokio::sync::Mutexを使用します。短い同期のみのロックには標準 Mutex を使用します - バックプレッシャーにはセマフォを使用 — 並行データベースクエリ、HTTPリクエスト、ファイル操作を制限します
- グレースフルシャットダウン —
tokio::signal::ctrl_c()とキャンセルトークンを使用して、終了前に作業をドレインします - ランタイム設定 — デフォルトは
#[tokio::main]を使用します。カスタムスレッド数とスタックサイズはruntime::Builderを使用します - Tracingの統合 — Tokio with
tracingクレートを使用します。スパンは非同期タスク境界を越えて自動的に伝播します
ライセンス: Apache-2.0(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- eliferjunior
- リポジトリ
- eliferjunior/Claude
- ライセンス
- Apache-2.0
- 最終更新
- 2026/4/14
Source: https://github.com/eliferjunior/Claude / ライセンス: Apache-2.0
関連スキル
doubt-driven-development
重要な判断はすべて、本番環境への展開前に新しい視点から対抗的レビューを実施します。速度より正確性が重要な場合、不慣れなコードを扱う場合、本番環境・セキュリティに関わるロジック・取り消し不可の操作など影響度が高い場合、または後でバグを修正するよりも今検証する方が効率的な場合に活用してください。
apprun-skills
TypeScriptを使用したAppRunアプリケーションのMVU設計に関する総合的なガイダンスが得られます。コンポーネントパターン、イベントハンドリング、状態管理(非同期ジェネレータを含む)、パラメータと保護機能を備えたルーティング・ナビゲーション、vistestを使用したテストに対応しています。AppRunコンポーネントの設計・レビュー、ルートの配線、状態フローの管理、AppRunテストの作成時に活用してください。
desloppify
コードベースのヘルスチェックと技術負債の追跡ツールです。コード品質、技術負債、デッドコード、大規模ファイル、ゴッドクラス、重複関数、コードスメル、命名規則の問題、インポートサイクル、結合度の問題についてユーザーが質問した場合に使用してください。また、ヘルススコアの確認、次の改善項目の提案、クリーンアップ計画の作成をリクエストされた際にも対応します。29言語に対応しています。
debugging-and-error-recovery
テストが失敗したり、ビルドが壊れたり、動作が期待と異なったり、予期しないエラーが発生したりした場合に、体系的な根本原因デバッグをガイドします。推測ではなく、根本原因を見つけて修正するための体系的なアプローチが必要な場合に使用してください。
test-driven-development
テスト駆動開発により実装を進めます。ロジックの実装、バグの修正、動作の変更など、あらゆる場面で活用できます。コードが正常に動作することを証明する必要がある場合、バグ報告を受けた場合、既存機能を修正する予定がある場合に使用してください。
incremental-implementation
変更を段階的に実施します。複数のファイルに影響する機能や変更を実装する場合に使用してください。大量のコードを一度に書こうとしている場合や、タスクが一度では完結できないほど大きい場合に活用します。