0Pricing
Learn Rust Coding · บทเรียน

สร้างเธรด

เรียกใช้โค้ดพร้อมกัน

สร้างเธรด เป็นบทเรียน Learn Rust Coding ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Learn Rust Coding และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 4 บทเรียน

เธรดคืออะไร

เธรดช่วยให้โปรแกรมเรียกใช้โค้ดพร้อมกันได้ ระบบปฏิบัติการสามารถจัดตารางเวลาให้หลายเธรดทำงานได้ จึงทำให้งานต่าง ๆ ทำงานทับซ้อนกันได้

ไลบรารีมาตรฐานของ Rust เปิดให้ใช้งานเธรดผ่านโมดูล std::thread เธรดเหล่านี้เป็นเธรดระดับระบบปฏิบัติการ หรือบางครั้งเรียกว่าเธรดแบบ 1:1

ในบทเรียนนี้ คุณจะเรียนรู้การเริ่มเธรดใหม่และควบคุมการทำงานของเธรดเหล่านั้น

การสร้างเธรดด้วย thread::spawn

คุณสร้างเธรดใหม่ได้โดยเรียก thread::spawn และส่งคลอเชอร์ให้ คลอเชอร์จะบรรจุโค้ดที่เธรดใหม่ต้องทำงาน

การเรียกใช้จะคืนค่าทันทีเป็น JoinHandle ขณะที่เธรดที่สร้างขึ้นทำงานอยู่เบื้องหลัง

use std::thread;

fn main() {
    thread::spawn(|| {
        println!("hello from a thread");
    });
    println!("hello from main");
}

main อาจทำงานเสร็จก่อน

เมื่อ main คืนค่า กระบวนการทั้งหมดจะสิ้นสุดลง แม้เธรดที่สร้างขึ้นจะยังทำงานอยู่ก็ตาม

ดังนั้นโปรแกรมด้านบนอาจพิมพ์ออกมาเพียงข้อความจาก main เธรดเบื้องหลังอาจไม่มีโอกาสทำงานก่อนกระบวนการจะสิ้นสุด

เราจึงต้องมีวิธีรอให้เธรดทำงานเสร็จ

การรอด้วย join

JoinHandle ที่ได้จาก spawn มีเมธอด join การเรียกใช้เมธอดนี้จะบล็อกเธรดปัจจุบันจนกว่าเธรดที่สร้างขึ้นจะทำงานเสร็จ

วิธีนี้รับรองว่าเธรดที่สร้างขึ้นจะทำงานจนเสร็จก่อนที่ main จะทำงานต่อ

use std::thread;

fn main() {
    let handle = thread::spawn(|| {
        println!("worker done");
    });
    handle.join().unwrap();
    println!("main done");
}

เอาต์พุตสลับแทรกกัน

เมื่อเธรดสองตัวทำงานพร้อมกัน เอาต์พุตของทั้งคู่อาจสลับแทรกกันในรูปแบบที่คาดเดาไม่ได้ ระบบปฏิบัติการเป็นผู้กำหนดตารางการทำงาน

การเรียกใช้โปรแกรมเดิมสองครั้งอาจให้ลำดับที่ต่างกัน อย่าพึ่งพาลำดับที่เฉพาะเจาะจงหากไม่มีการประสานงาน

use std::thread;

fn main() {
    let handle = thread::spawn(|| {
        for i in 1..4 {
            println!("thread: {}", i);
        }
    });
    for i in 1..4 {
        println!("main: {}", i);
    }
    handle.join().unwrap();
}

การหยุดชั่วคราวด้วย sleep

คุณหยุดเธรดชั่วคราวได้ด้วย thread::sleep ซึ่งรับค่า Duration การทำเช่นนี้จะคืนเวลาให้ CPU เพื่อให้เธรดอื่นทำงานต่อได้

การหยุดชั่วคราวมีประโยชน์ในตัวอย่างเพื่อให้เห็นการสลับแทรกได้ชัดเจนขึ้น แต่ไม่ควรใช้แทนการประสานงานจริง

use std::thread;
use std::time::Duration;

fn main() {
    thread::spawn(|| {
        for i in 1..4 {
            println!("spawned: {}", i);
            thread::sleep(Duration::from_millis(1));
        }
    });
    thread::sleep(Duration::from_millis(10));
}

การสร้างเธรดจำนวนมาก

คุณสามารถสร้างเธรดหลายตัวภายในลูป และรวบรวมตัวจัดการของเธรดเหล่านั้นไว้ในเวกเตอร์ได้

จากนั้นจึงวนซ้ำผ่านเวกเตอร์และเรียก join กับตัวจัดการแต่ละตัว เพื่อรับรองว่าเธรดทุกตัวทำงานเสร็จก่อนโปรแกรมจะจบ

use std::thread;

fn main() {
    let mut handles = vec![];
    for id in 0..3 {
        let h = thread::spawn(move || {
            println!("thread {}", id);
        });
        handles.push(h);
    }
    for h in handles {
        h.join().unwrap();
    }
}

การตั้งชื่อเธรดด้วย Builder

ชนิด thread::Builder ช่วยให้คุณกำหนดค่าเธรดก่อนสร้างได้ คุณสามารถตั้งชื่อและขนาดสแตกได้

เธรดที่มีชื่อทำให้ข้อความแพนิกและการแก้ไขข้อผิดพลาดอ่านได้ง่ายขึ้น

use std::thread;

fn main() {
    let h = thread::Builder::new()
        .name("worker".into())
        .spawn(|| {
            println!("running in named thread");
        })
        .unwrap();
    h.join().unwrap();
}

แพนิกยังคงอยู่ภายในเธรด

หากเธรดที่สร้างขึ้นเกิดแพนิก โดยค่าเริ่มต้นจะไม่ทำให้โปรแกรมทั้งหมดหยุดทำงาน แพนิกจะถูกจำกัดอยู่ภายในเธรดนั้น

เมื่อคุณเรียก join กับเธรดที่เกิดแพนิก คุณจะได้รับค่า Err ทำให้เธรดแม่ตรวจพบความล้มเหลวได้

use std::thread;

fn main() {
    let h = thread::spawn(|| {
        panic!("boom");
    });
    let result = h.join();
    println!("joined, is_err = {}", result.is_err());
}

ข้อมูลเธรดปัจจุบัน

คุณสามารถตรวจสอบเธรดที่กำลังทำงานอยู่ด้วย thread::current ซึ่งคืนค่าตัวจัดการที่เมธอด name ใช้ดูชื่อเธรด (ถ้ามี)

เธรดหลักก็เป็นเธรดจริงเช่นกัน และโดยทั่วไปมีชื่อว่า main

use std::thread;

fn main() {
    let current = thread::current();
    println!("name: {:?}", current.name());
}

การคืนค่าจากเธรด

คลอเชอร์ที่ส่งให้ spawn สามารถคืนค่าได้ ค่านั้นจะถูกห่อไว้ใน Ok เมื่อคุณเรียก join

นี่เป็นวิธีง่าย ๆ ในการคำนวณบางอย่างบนเธรดอื่น แล้วอ่านผลลัพธ์ในภายหลัง

use std::thread;

fn main() {
    let h = thread::spawn(|| {
        let sum: i32 = (1..=10).sum();
        sum
    });
    let total = h.join().unwrap();
    println!("total = {}", total);
}

ตรวจสอบความเข้าใจ

ทดสอบความเข้าใจของคุณเกี่ยวกับการสร้างเธรด

สรุปทบทวน

คุณได้เรียนรู้การเริ่มเธรดด้วย thread::spawn และคลอเชอร์ ซึ่งคืนค่าเป็น JoinHandle

การเรียก join จะรอให้ทำงานเสร็จ และส่งต่อค่าที่คืนกลับมาหรือแพนิก เอาต์พุตระหว่างเธรดอาจสลับแทรกกันอย่างคาดเดาไม่ได้ และ Builder ช่วยให้คุณตั้งชื่อเธรดได้

ต่อไปคุณจะได้เรียนรู้วิธีย้ายข้อมูลเข้าไปในเธรดที่สร้างขึ้น

คำถามที่พบบ่อย

บทเรียน “สร้างเธรด” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “สร้างเธรด” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Learn Rust Coding ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “สร้างเธรด”

เรียกใช้โค้ดพร้อมกัน คุณปฏิบัติ Learn Rust Coding ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Learn Rust Coding หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Learn Rust Coding บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “สร้างเธรด” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Learn Rust Coding นี้ได้ไหม

ได้ บทเรียน Learn Rust Coding ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. สร้างเธรด
  2. ย้ายข้อมูลเข้าเธรด
  3. ใช้ข้อมูลร่วมกับ Arc และ Mutex
  4. รอเธรดและรวบรวมผลลัพธ์
← กลับไปที่ Learn Rust Coding