std::mutex, lock_guard และ unique_lock
ปกป้องสถานะที่ใช้ร่วมกันด้วย mutex และตัวช่วยล็อกแบบ RAII
std::mutex, lock_guard และ unique_lock เป็นบทเรียน C++ Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C++ Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดจึงต้องใช้มิวเท็กซ์
เมื่อมีหลายเธรดเข้าถึงข้อมูลเดียวกัน เธรดเหล่านั้นจะแข่งขันกันเข้าถึงข้อมูล มิวเท็กซ์รับประกันการกีดกันร่วม โดยจะมีเธรดเพียงหนึ่งตัวเท่านั้นที่ถือ lock ได้ในแต่ละครั้ง
พื้นฐานของ std::mutex
สร้าง เรียก lock และเรียก unlock การใช้ lock ด้วยตนเองมีโอกาสเกิดข้อผิดพลาดได้ง่าย — ควรใช้ตัวช่วย RAII เสมอ
#include <mutex>
std::mutex mtx;
mtx.lock();
// critical section
mtx.unlock();std::lock_guard: lock แบบ RAII
lock แบบ RAII ที่เรียบง่ายที่สุด จะเรียก lock ในตัวสร้างและเรียก unlock ในตัวทำลาย ทำงานได้เหมาะสมอย่างยิ่งกับส่วนวิกฤตที่ไม่โยนข้อยกเว้น
std::mutex mtx;
int counter = 0;
void increment() {
std::lock_guard<std::mutex> lock(mtx);
++counter;
}std::scoped_lock (C++17)
คล้ายกับ lock_guard แต่สามารถเรียก lock กับมิวเท็กซ์หลายตัวพร้อมกันได้โดยไม่เกิดเดดล็อก ควรเลือกใช้ในโค้ดสมัยใหม่
#include <mutex>
std::scoped_lock lock(mtx1, mtx2, mtx3); // locks all atomicallystd::unique_lock: lock ที่ยืดหยุ่น
มีความสามารถมากกว่า lock_guard:
- สามารถเรียก unlock และเรียก lock ใหม่ระหว่างขอบเขตได้
- สามารถย้ายได้ (โอนความเป็นเจ้าของได้)
- ใช้ร่วมกับตัวแปรเงื่อนไขได้
std::unique_lock<std::mutex> lock(mtx);
lock.unlock(); // release temporarily
// ... do something without the lock ...
lock.lock(); // reacquireการหลีกเลี่ยงเดดล็อก
เธรดสองตัวอาจเกิดเดดล็อกได้หากเรียก lock ตามลำดับที่แตกต่างกัน ให้เรียก lock ตามลำดับทั่วทั้งโปรแกรมที่สอดคล้องกัน หรือใช้ std::scoped_lock กับมิวเท็กซ์หลายตัว
std::lock สำหรับมิวเท็กซ์หลายตัว
ก่อน C++17 ให้ใช้ std::lock เพื่อเรียก lock กับมิวเท็กซ์หลายตัวอย่างเป็นอะตอมิก ส่วน std::scoped_lock ใน C++17 ใช้งานได้ชัดเจนกว่า
มิวเท็กซ์แบบเรียกซ้ำ
std::recursive_mutex อนุญาตให้เธรดเรียก lock กับมิวเท็กซ์ตัวเดิมได้หลายครั้ง โดยทั่วไปนี่เป็นสัญญาณว่าการออกแบบมีปัญหา — ควรปรับโครงสร้างใหม่แทน
try_lock และ timed_mutex
try_lock จะคืนค่าทันทีหากมีการถือ lock อยู่ std::timed_mutex รองรับความพยายามเรียก lock ที่จำกัดเวลา
lock สำหรับผู้อ่านและผู้เขียน
std::shared_mutex (C++17) อนุญาตให้มีผู้อ่านหลายตัวทำงานพร้อมกัน หรือมีผู้เขียนเพียงตัวเดียวที่เข้าถึงแบบผูกขาด ใช้กับงานที่อ่านข้อมูลเป็นหลัก
std::shared_mutex sm;
void read() { std::shared_lock lk(sm); /* read */ }
void write() { std::unique_lock lk(sm); /* write */ }ข้อแลกเปลี่ยนด้านความละเอียด
การใช้ lock ในระดับหยาบเกินไปจะลดการทำงานพร้อมกัน ส่วนการใช้ lock ในระดับละเอียดเกินไปจะเพิ่มค่าใช้จ่าย ควรวัดประสิทธิภาพและปรับแต่ง
ทางเลือกแบบไม่ใช้ lock
สำหรับสถานการณ์ที่มีการแย่งใช้ทรัพยากรสูง ให้พิจารณาโครงสร้างข้อมูลแบบไม่ใช้ lock (ตัวแปรอะตอมิก คิวแบบไม่ใช้ lock) การเขียนให้ถูกต้องทำได้ยากกว่ามาก — ควรใช้เฉพาะเมื่อจำเป็นและผ่านการตรวจสอบแล้ว
ตรวจสอบอย่างรวดเร็ว
ควรเลือก lock แบบ RAII ใดเมื่อต้องใช้ lock กับมิวเท็กซ์ หลายตัว พร้อมกัน
สรุปทบทวน
ใช้ std::lock_guard สำหรับส่วนวิกฤตที่เรียบง่าย ใช้ std::scoped_lock สำหรับมิวเท็กซ์หลายตัว และใช้ std::unique_lock เมื่อต้องการความยืดหยุ่น (ตัวแปรเงื่อนไข การเรียก unlock ด้วยตนเอง) ควรใช้ RAII เสมอ — อย่าเรียก lock หรือ unlock ด้วยตนเอง
เรียนรู้ C++ ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 51
- บทเรียน
- 203
คำถามที่พบบ่อย
บทเรียน “std::mutex, lock_guard และ unique_lock” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “std::mutex, lock_guard และ unique_lock” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C++ Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “std::mutex, lock_guard และ unique_lock”
ปกป้องสถานะที่ใช้ร่วมกันด้วย mutex และตัวช่วยล็อกแบบ RAII คุณปฏิบัติ C++ Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C++ Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C++ Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “std::mutex, lock_guard และ unique_lock” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C++ Academy นี้ได้ไหม
ได้ บทเรียน C++ Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- std::thread: การรวมและการแยกเธรด
- std::mutex, lock_guard และ unique_lock
- ตัวแปรเงื่อนไขและรูปแบบผู้ปฏิบัติงาน
- พื้นฐาน std::async และ std::future