Howard ตอบคำถามได้ดีอยู่แล้วและ Nicol ได้ให้ประเด็นที่ดีเกี่ยวกับประโยชน์ของการมีชนิดตัวชี้ที่ใช้ร่วมกันมาตรฐานเดียวแทนที่จะเป็นชนิดที่เข้ากันไม่ได้
แม้ว่าฉันจะเห็นด้วยอย่างสมบูรณ์กับการตัดสินใจของคณะกรรมการ แต่ฉันคิดว่ามีประโยชน์บางอย่างในการใช้shared_ptr
ประเภทที่ไม่ตรงกัน- เหมือนในกรณีพิเศษดังนั้นฉันจึงตรวจสอบหัวข้อนี้สองสามครั้ง
ถ้าฉันไม่ได้ใช้เธรดหลายเธรดหรือฉันกำลังใช้เธรดหลายเธรด แต่ฉันไม่ได้แชร์ความเป็นเจ้าของพอยน์เตอร์ข้ามเธรดตัวชี้สมาร์ทอะตอมจะมากเกินไป
ด้วย GCC เมื่อโปรแกรมของคุณไม่ใช้หลายเธรด shared_ptr ไม่ได้ใช้ atomic ops สำหรับ refcount สิ่งนี้ทำได้โดยการอัปเดตจำนวนการอ้างอิงผ่านฟังก์ชัน wrapper ที่ตรวจจับว่าโปรแกรมเป็นแบบมัลติเธรดหรือไม่ (บน GNU / Linux ซึ่งทำได้ง่ายๆโดยการตรวจสอบว่าโปรแกรมเชื่อมโยงไปยังlibpthread.so
) และส่งไปยังการดำเนินการแบบอะตอมหรือไม่ใช่อะตอมตามนั้น
ฉันรู้ว่าหลายปีที่ผ่านมาว่าเป็นเพราะของ GCC shared_ptr<T>
จะดำเนินการในแง่ของ__shared_ptr<T, _LockPolicy>
ชั้นฐาน__shared_ptr<T, __gnu_cxx::_S_single>
ก็เป็นไปได้ที่จะใช้ชั้นฐานกับเธรดเดียวล็อคนโยบายแม้ในรหัสแบบมัลติเธรดโดยใช้อย่างชัดเจน น่าเสียดายเพราะนั่นไม่ใช่กรณีการใช้งานที่ตั้งใจไว้มันจึงไม่ทำงานได้ดีที่สุดก่อน GCC 4.9 และการดำเนินการบางอย่างยังคงใช้ฟังก์ชันของ wrapper ดังนั้นจึงส่งไปที่การปฏิบัติการปรมาณูแม้ว่าคุณจะร้องขอ_S_single
นโยบายอย่างชัดเจนก็ตาม ดูประเด็น (2) ที่http://gcc.gnu.org/ml/libstdc++/2007-10/msg00180.htmlสำหรับรายละเอียดเพิ่มเติมและการแก้ไข GCC เพื่อให้สามารถใช้งานแบบไม่ใช้อะตอมได้แม้ในแอปมัลติเธรด ฉันนั่งบนแพตช์นั้นมาหลายปี แต่ในที่สุดฉันก็ตกลงสำหรับ GCC 4.9 ซึ่งช่วยให้คุณใช้เทมเพลตนามแฝงเช่นนี้เพื่อกำหนดประเภทตัวชี้ที่ใช้ร่วมกันที่ไม่ปลอดภัยต่อเธรด แต่เร็วกว่าเล็กน้อย:
template<typename T>
using shared_ptr_unsynchronized = std::__shared_ptr<T, __gnu_cxx::_S_single>;
ประเภทนี้จะไม่สามารถทำงานร่วมกันได้std::shared_ptr<T>
และจะปลอดภัยที่จะใช้ก็ต่อเมื่อได้รับการรับรองว่าshared_ptr_unsynchronized
วัตถุจะไม่ถูกแชร์ระหว่างเธรดโดยไม่มีการซิงโครไนซ์ที่ผู้ใช้ระบุเพิ่มเติม
แน่นอนว่านี่ไม่สามารถพกพาได้อย่างสมบูรณ์ แต่บางครั้งก็ไม่เป็นไร ด้วยตัวประมวลผลล่วงหน้าที่ถูกต้องแฮ็กโค้ดของคุณจะยังคงทำงานได้ดีกับการใช้งานอื่น ๆ หากshared_ptr_unsynchronized<T>
เป็นนามแฝงสำหรับshared_ptr<T>
GCC ก็จะเร็วขึ้นเล็กน้อย
หากคุณใช้ GCC ก่อน 4.9 คุณสามารถใช้สิ่งนั้นได้โดยการเพิ่ม_Sp_counted_base<_S_single>
ความเชี่ยวชาญเฉพาะทางให้กับโค้ดของคุณเอง (และทำให้มั่นใจว่าจะไม่มีใครสร้างอินสแตนซ์__shared_ptr<T, _S_single>
โดยไม่รวมความเชี่ยวชาญพิเศษเพื่อหลีกเลี่ยงการละเมิด ODR) การเพิ่มความเชี่ยวชาญพิเศษstd
ประเภทดังกล่าวนั้นไม่ได้กำหนดไว้ในทางเทคนิค แต่จะ ทำงานในทางปฏิบัติเพราะในกรณีนี้ไม่มีความแตกต่างระหว่างฉันเพิ่มความเชี่ยวชาญพิเศษใน GCC หรือคุณเพิ่มลงในรหัสของคุณเอง