The Chromium Chronicle #25: หมายเหตุเกี่ยวกับความปลอดภัยของเทรด

ตอนที่ 25: โดย Victor Costan ใน SFO (ตุลาคม 2021)
ตอนก่อนหน้า

ใน C++ การตัดสินเกี่ยวกับความเป็นไปได้ของการแข่งขันด้านข้อมูลจะอยู่ที่ข้อพิสูจน์ความถูกต้องเล็กๆ น้อยๆ เกี่ยวกับความปลอดภัยของชุดข้อความสำหรับการเข้าถึงข้อมูลทั้งหมดของสมาชิก การพิสูจน์เหล่านี้ช่วยเพิ่มความหนักแน่นทางจิตใจได้เป็นอย่างมาก โดยเฉพาะอย่างยิ่งเมื่อตรวจสอบหรือเปลี่ยนโครงสร้างโค้ด เฟรมเวิร์กการวิเคราะห์แบบคงที่ของ Clang เข้ามาแทนที่การทดสอบทั่วไปด้านความปลอดภัยของเทรด

เพิ่ม GUARDED_BY_CONTEXT() ไปยังสมาชิกในข้อมูลในชั้นเรียนที่ไม่ปลอดภัยของชุดข้อความ

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

#include "base/sequence_checker.h"  // for SEQUENCE_CHECKER()
#include "base/thread_annotations.h"  // for GUARDED_BY_CONTEXT()

class Cache {
  // Methods here.
 private:
  SEQUENCE_CHECKER(sequence_checker_);
  base::flat_map<std::string, std::string> data_ GUARDED_BY_CONTEXT(sequence_checker_);
};

Clang บังคับใช้การตรวจสอบลำดับ

เพื่อเป็นการตอบแทนการใส่คำอธิบายประกอบให้กับสมาชิกข้อมูล Clang จะดูแลให้วิธีการใดก็ตามที่เข้าถึงข้อมูลมีการตรวจสอบความปลอดภัยในลำดับก่อนที่จะดำเนินการ เมื่อมีการย้ายโค้ดในการปรับโครงสร้าง Clang จะยังคงบังคับใช้คำอธิบายประกอบ GUARDED_BY_CONTEXT() ต่อไป

void Cache::Set(base::StringPiece key, base::StringPiece value) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);  // Clang warns without this.
  data_.emplace(key, value);
}

เพิ่ม GUARDED_BY() ไปยังสมาชิกข้อมูลในชั้นเรียนที่ปลอดภัยสำหรับชุดข้อความที่ใช้ Mutex

บางคลาสใน Chrome ต้องใช้การล็อกเพื่อความปลอดภัยของชุดข้อความ ในกรณีเหล่านี้ ให้ระบุคำอธิบายประกอบให้กับสมาชิกข้อมูลทั้งหมดที่ไม่ปลอดภัยสำหรับชุดข้อความ คำอธิบายประกอบแต่ละรายการจะชี้ไปที่ Mutex ซึ่งต้องเก็บไว้ขณะเข้าถึงสมาชิกข้อมูล

#include "base/thread_annotations.h"  // for GUARDED_BY()

class ThreadSafeCache {
  // Methods here.
  private:
    base::Lock lock_;
    base::flat_map<std::string, std::string> data_ GUARDED_BY(lock_);
};

Clang บังคับใช้การได้ล็อก

โปรดรอและปล่อยให้คอมไพเลอร์ตรวจสอบว่า base::AutoLock แต่ละรายการกำหนดขอบเขตได้อย่างถูกต้อง รวมถึงการจับคู่การเรียก Acquire() และ Release() อย่างถูกต้อง

void ThreadSafeCache::Set(base::StringPiece key, base::StringPiece value) {
  base::AutoLock auto_lock(lock_);  // Clang warns without this.
  data_.emplace(key, value);
}