สร้างแอปพลิเคชันอะซิงโครนัสด้วย Tokio
ใช้รันไทม์ Tokio เพื่อเรียกใช้งานภารกิจอะซิงโครนัสอย่างมีประสิทธิภาพ พร้อมจัดการ IO และการดำเนินการอื่น ๆ แบบพร้อมกัน
สร้างแอปพลิเคชันอะซิงโครนัสด้วย Tokio เป็นบทเรียน Learn Rust Coding ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 3 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Learn Rust Coding และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 3 บทเรียน
ทำความรู้จักรันไทม์ Tokio
ยินดีต้อนรับกลับมา! ในบทเรียนก่อนหน้านี้ คุณได้เรียนรู้เกี่ยวกับ async และ await แต่ฟังก์ชัน async ทำงานจริงได้อย่างไร
รันไทม์แบบอะซิงโครนัสอย่าง Tokio เข้ามาช่วยในจุดนี้ Tokio เป็นไลบรารีอันทรงพลังที่จัดเตรียมสภาพแวดล้อมการทำงานสำหรับโค้ด Rust แบบอะซิงโครนัสของคุณ
- จัดตารางเวลาและเรียกใช้
Futures - จัดการการดำเนินการนำเข้า/ส่งออกที่ไม่บล็อกการทำงาน
- จัดการทาสก์ที่ทำงานพร้อมกันอย่างมีประสิทธิภาพ
เรียกใช้โค้ด Async ของคุณ
ในการเริ่มต้นใช้งาน Tokio โดยทั่วไปคุณจะใช้มาโครแอตทริบิวต์ #[tokio::main] มาโครนี้จะแปลง async fn main() ของคุณให้เป็น fn main() มาตรฐาน ซึ่งเริ่มต้นรันไทม์ Tokio และเรียกใช้โค้ดแบบอะซิงโครนัสของคุณ
ลองนึกภาพว่านี่คือจุดเริ่มต้นของแอปพลิเคชันแบบอะซิงโครนัสของคุณ
use tokio;
#[tokio::main]
async fn main() {
println!("Hello from Tokio!");
}สร้างทาสก์ Async ใหม่
หนึ่งในความสามารถหลักของ Tokio คือการเรียกใช้การดำเนินการแบบอะซิงโครนัสหลายรายการพร้อมกัน คุณทำเช่นนี้ได้โดยใช้ tokio::spawn
tokio::spawn รับ Future แล้วจัดตารางเวลาให้ทำงานบนรันไทม์ Tokio ทำให้ทาสก์หลักของคุณทำงานต่อได้ ขณะที่ทาสก์ที่สร้างขึ้นทำงานอยู่เบื้องหลัง
- ไม่บล็อกการทำงาน
- ส่งคืน
JoinHandleเพื่อรอจนทำงานเสร็จ - ทาสก์ทำงานอย่างเป็นอิสระต่อกัน
การทำงานของ <code>tokio::spawn</code>
มาดูกันว่า tokio::spawn ช่วยให้คุณเรียกใช้โค้ดพร้อมกันได้อย่างไร โปรดสังเกตว่าข้อความทั้งสองปรากฏขึ้น แต่ข้อความ 'done' อาจแสดงก่อนข้อความ 'task complete' เนื่องจากการหยุดพัก
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() {
// Spawn a new task
let handle = tokio::spawn(async {
sleep(Duration::from_secs(1)).await;
println!("Async task complete!");
});
println!("Main task continuing...");
// Wait for the spawned task to finish
handle.await.unwrap();
println!("All tasks done.");
}รอทาสก์หลายรายการ
เมื่อมีทาสก์หลายรายการ คุณมักจำเป็นต้องรอให้ทาสก์ทั้งหมดทำงานเสร็จ Tokio มีมาโคร tokio::join! สำหรับจุดประสงค์นี้
tokio::join! ช่วยให้รอ futures หลายรายการพร้อมกันและรวมผลลัพธ์ของรายการเหล่านั้นเข้าด้วยกัน การทำงานคล้ายกับการรอ `await` กับ JoinHandles หลายรายการ แต่กระชับกว่าสำหรับชุด futures ที่กำหนดตายตัว
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() {
let task1 = async {
sleep(Duration::from_secs(1)).await;
println!("Task 1 finished");
1
};
let task2 = async {
sleep(Duration::from_millis(500)).await;
println!("Task 2 finished");
2
};
let (result1, result2) = tokio::join!(task1, task2);
println!("Results: {}, {}", result1, result2);
}การนำเข้า/ส่งออกไฟล์แบบ Async ด้วย Tokio
การดำเนินการกับไฟล์แบบดั้งเดิมอาจบล็อกเธรด ซึ่งไม่เหมาะกับแอปพลิเคชันแบบอะซิงโครนัส โมดูล tokio::fs ของ Tokio มีการดำเนินการกับระบบไฟล์ในรูปแบบอะซิงโครนัส
วิธีนี้ช่วยให้แอปพลิเคชันของคุณยังตอบสนองได้ แม้กำลังอ่านไฟล์ขนาดใหญ่หรือดำเนินการกับไฟล์หลายรายการ เนื่องจากการนำเข้า/ส่งออกได้รับการจัดการแบบไม่บล็อกการทำงาน
tokio::fs::read_to_stringtokio::fs::writetokio::fs::Fileสำหรับการควบคุมที่มากขึ้น
อ่านไฟล์แบบอะซิงโครนัส
ต่อไปนี้คือตัวอย่างการอ่านไฟล์แบบอะซิงโครนัสโดยใช้ tokio::fs::read_to_string เพื่อให้โค้ดนี้ทำงานได้ โปรดตรวจสอบว่ามีไฟล์ชื่อ hello.txt อยู่ในไดเรกทอรีเดียวกับโปรเจกต์ Rust ของคุณ (เช่น ภายใน src/ หรือที่โฟลเดอร์รากของโปรเจกต์) และไฟล์มีเนื้อหาอยู่
use tokio::fs;
#[tokio::main]
async fn main() {
let path = "hello.txt";
// Create a dummy file for the example if it doesn't exist
// In a real app, you'd handle file creation/existence more robustly
if let Err(_) = fs::metadata(path).await {
fs::write(path, "Hello, Tokio file!").await.unwrap();
}
match fs::read_to_string(path).await {
Ok(content) => println!("File content: '{}'", content),
Err(e) => eprintln!("Error reading file: {}", e),
}
}การดำเนินการเครือข่ายแบบ Async
Tokio โดดเด่นอย่างแท้จริงในการเขียนโปรแกรมเครือข่าย โมดูล tokio::net มีองค์ประกอบพื้นฐานแบบไม่บล็อกการทำงานสำหรับการสื่อสารผ่าน TCP และ UDP
สิ่งนี้สำคัญอย่างยิ่งต่อการสร้างเซิร์ฟเวอร์หรือไคลเอ็นต์ประสิทธิภาพสูงที่รองรับการเชื่อมต่อจำนวนมากพร้อมกันได้ โดยไม่ต้องใช้เธรดแยกสำหรับแต่ละการเชื่อมต่อ
tokio::net::TcpListenerสำหรับเซิร์ฟเวอร์tokio::net::TcpStreamสำหรับการเชื่อมต่อจากไคลเอ็นต์
โครงสร้างพื้นฐานของเซิร์ฟเวอร์ TCP แบบ Async
แม้เซิร์ฟเวอร์เต็มรูปแบบจะซับซ้อน แต่โค้ดส่วนนี้แสดงลูปหลักของเซิร์ฟเวอร์ TCP แบบอะซิงโครนัสที่ใช้ Tokio โดยจะรอรับการเชื่อมต่อขาเข้าและพิมพ์ข้อความสำหรับแต่ละการเชื่อมต่อ ลองเรียกใช้โค้ดนี้ แล้วเปิดเบราว์เซอร์ไปที่ http://127.0.0.1:8080 เพื่อดูการเชื่อมต่อ
use tokio::net::TcpListener;
#[tokio::main]
async fn main() {
let listener = TcpListener::bind("127.0.0.1:8080").await.unwrap();
println!("Listening on: {}", listener.local_addr().unwrap());
loop {
let (socket, addr) = listener.accept().await.unwrap();
println!("Accepted connection from: {}", addr);
// In a real server, you'd spawn a task to handle the socket
// tokio::spawn(async move { handle_connection(socket).await; });
}
}
// fn handle_connection(socket: TcpStream) { /* ... */ } // Placeholderโจทย์ท้าทายทาสก์ของ Tokio
พิจารณาโค้ด Rust ต่อไปนี้ที่ใช้ Tokio เมื่อโปรแกรมนี้ทำงาน ข้อความใดจะถูกพิมพ์ลงคอนโซลเป็นข้อความแรก
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() {
tokio::spawn(async {
sleep(Duration::from_millis(200)).await;
println!("Task 1: Done");
});
tokio::spawn(async {
sleep(Duration::from_millis(100)).await;
println!("Task 2: Done");
});
println!("Main: Starting tasks...");
sleep(Duration::from_millis(300)).await;
println!("Main: Finishing.");
}ทบทวน: สร้างโปรแกรมด้วย Tokio
คุณได้ก้าวสำคัญสู่การสร้างแอปพลิเคชันแบบอะซิงโครนัสด้วย Rust และ Tokio แล้ว!
- Tokio ทำหน้าที่เป็นรันไทม์แบบ async ซึ่งเรียกใช้โค้ด
asyncของคุณ #[tokio::main]คือจุดเริ่มต้นแบบ async ของโปรแกรมtokio::spawnช่วยให้คุณเรียกใช้ทาสก์หลายรายการพร้อมกันtokio::join!ช่วยรอ futures หลายรายการ- Tokio มีการนำเข้า/ส่งออกที่ไม่บล็อกการทำงานสำหรับไฟล์ (
tokio::fs) และเครือข่าย (tokio::net)
เครื่องมือเหล่านี้เป็นพื้นฐานสำคัญสำหรับการสร้างแอปพลิเคชัน Rust ที่ทำงานพร้อมกันได้มากและตอบสนองได้ดี ฝึกฝนต่อไปนะครับ!
คำถามที่พบบ่อย
บทเรียน “สร้างแอปพลิเคชันอะซิงโครนัสด้วย Tokio” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “สร้างแอปพลิเคชันอะซิงโครนัสด้วย Tokio” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Learn Rust Coding ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 3 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “สร้างแอปพลิเคชันอะซิงโครนัสด้วย Tokio”
ใช้รันไทม์ Tokio เพื่อเรียกใช้งานภารกิจอะซิงโครนัสอย่างมีประสิทธิภาพ พร้อมจัดการ IO และการดำเนินการอื่น ๆ แบบพร้อมกัน คุณปฏิบัติ Learn Rust Coding ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Learn Rust Coding หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Learn Rust Coding บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 3 บทเรียน
บทเรียน “สร้างแอปพลิเคชันอะซิงโครนัสด้วย Tokio” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Learn Rust Coding นี้ได้ไหม
ได้ บทเรียน Learn Rust Coding ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- รู้จัก Async/Await
- สร้างแอปพลิเคชันอะซิงโครนัสด้วย Tokio
- ทำงานกับ Futures และ Tasks