กลับไปหน้าบทความ

อ่าน 7 นาที

การจัดหาทรัพยากรเป็นการเริ่มต้น

เปลี่ยนทางจากตัวพิมพ์ใหญ่อื่น/การเปลี่ยนเส้นทางที่ไม่สามารถพิมพ์ได้

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

การจัดหาทรัพยากรเป็นการเริ่มต้น

การได้มาซึ่งทรัพยากรคือการเริ่มต้น ( RAII ) [ 1 ]เป็นสำนวนการเขียนโปรแกรม[ 2 ]ที่ใช้ใน ภาษาการเขียนโปรแกรม เชิงวัตถุและแบบคงที่ หลาย ภาษาเพื่ออธิบายพฤติกรรมของภาษาเฉพาะ ใน RAII การถือครองทรัพยากรเป็นค่าคงที่ของคลาสและเชื่อมโยงกับอายุการใช้งานของวัตถุการจัดสรร (หรือการได้มาซึ่งทรัพยากร) จะทำในระหว่างการสร้างวัตถุ (โดยเฉพาะการเริ่มต้น) โดยคอนสตรัคเตอร์ในขณะที่การปลดปล่อย (การปล่อย) ทรัพยากรจะทำในระหว่างการทำลายวัตถุ (โดยเฉพาะการสิ้นสุด) โดยดีสตรัคเตอร์กล่าวอีกนัยหนึ่ง การได้มาซึ่งทรัพยากรต้องสำเร็จเพื่อให้การเริ่มต้นสำเร็จ ดังนั้น ทรัพยากรจึงรับประกันว่าจะถูกถือครองระหว่างช่วงเวลาที่การเริ่มต้นเสร็จสิ้นและการเริ่มต้นการสิ้นสุด (การถือครองทรัพยากรเป็นค่าคงที่ของคลาส) และจะถูกถือครองเฉพาะเมื่อวัตถุยังมีชีวิตอยู่ ดังนั้น หากไม่มีการรั่วไหลของวัตถุ ก็จะไม่มี การรั่วไหล ของ ทรัพยากร

RAII มีความเกี่ยวข้องอย่างเด่นชัดกับC++ซึ่งเป็นต้นกำเนิด แต่ยังรวมถึงAda [ 3 ] Vala [ 4 ]และ Rust [ 5 ] เทคนิคนี้ได้รับการพัฒนาขึ้นเพื่อการจัดการทรัพยากรที่ปลอดภัยจากข้อยกเว้นใน C++ [ 6 ]ในช่วงปี 1984–1989 โดยส่วนใหญ่โดยBjarne StroustrupและAndrew Koenig [ 7 ]และ คำนี้เองก็ถูก บัญญัติขึ้นโดย Stroustrup [ 8 ]

ชื่ออื่นๆ สำหรับสำนวนนี้ ได้แก่Constructor Acquires, Destructor Releases (CADRe) [ 9 ]และรูปแบบการใช้งานเฉพาะอย่างหนึ่งเรียกว่าScope-based Resource Management (SBRM) [ 10 ]คำศัพท์หลังนี้ใช้สำหรับกรณีพิเศษของตัวแปรอัตโนมัติ RAII เชื่อมโยงทรัพยากรกับอายุการใช้ งานของวัตถุ ซึ่งอาจไม่ตรงกับการเข้าและออกของขอบเขต (โดยเฉพาะอย่างยิ่งตัวแปรที่จัดสรรบนพื้นที่จัดเก็บว่างจะมีอายุการใช้งานที่ไม่เกี่ยวข้องกับขอบเขตใดๆ) อย่างไรก็ตาม การใช้ RAII สำหรับตัวแปรอัตโนมัติ (SBRM) เป็นกรณีการใช้งานที่พบบ่อยที่สุด

ตัวอย่างภาษา C++

ตัวอย่างต่อไปนี้แสดงวิธีการใช้งาน RAII สำหรับการเข้าถึงไฟล์และ การล็อก แบบมิวเท็กซ์ :

import std ;using std :: mutex ; using std :: ofstream ; using std :: runtime_error ; using std :: scoped_lock ; using std :: string ;void writeToFile ( const string & message ) { // mutex ใช้เพื่อป้องกันการเข้าถึงไฟล์ (ซึ่งใช้ร่วมกันระหว่างเธรด) static mutex m ;// ล็อก mutex ก่อนเข้าถึงไฟล์scoped_lock < mutex > lock ( m );// ลองเปิดไฟล์ofstream f { "example.txt" }; if ( ! f . is_open ()) { throw runtime_error ( "ไม่สามารถเปิดไฟล์ได้" ); }// เขียนข้อความลงไฟล์std :: println ( f , message );// ไฟล์จะถูกปิดก่อนเมื่อออกจากขอบเขต (โดยไม่คำนึงถึงข้อยกเว้น) // มิวเท็กซ์จะถูกปลดล็อกเป็นอันดับสอง (จากตัวทำลายล็อก) เมื่อออกจากขอบเขต// (โดยไม่คำนึงถึงข้อยกเว้น) }

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

ตัวแปรโลคอลช่วยให้จัดการทรัพยากรหลายรายการภายในฟังก์ชันเดียวได้ง่าย: ตัวแปรเหล่านั้นจะถูกทำลายในลำดับย้อนกลับของการสร้าง และวัตถุจะถูกทำลายก็ต่อเมื่อสร้างเสร็จสมบูรณ์แล้วเท่านั้น นั่นคือ หากไม่มีข้อยกเว้นแพร่กระจายมาจากตัวสร้าง[ 13 ]

การใช้ RAII ช่วยลดความซับซ้อนในการจัดการทรัพยากร ลดขนาดโค้ดโดยรวม และช่วยให้มั่นใจได้ถึงความถูกต้องของโปรแกรม ดังนั้น RAII จึงได้รับการแนะนำโดยแนวทางมาตรฐานอุตสาหกรรม[ 14 ] และไลบรารีมาตรฐาน C++ ส่วนใหญ่ก็ปฏิบัติตามรูปแบบนี้[ 15 ]

ประโยชน์

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

การห่อหุ้มข้อมูล (Encapsulation) เกิดขึ้นเนื่องจากตรรกะการจัดการทรัพยากรถูกกำหนดไว้เพียงครั้งเดียวในคลาส ไม่ใช่ที่จุดเรียกใช้งานแต่ละครั้ง ความปลอดภัยจากข้อยกเว้น (Exception safety) เกิดขึ้นกับทรัพยากรบนสแต็ก (ทรัพยากรที่ถูกปล่อยในขอบเขตเดียวกันกับที่ได้รับมา) โดยการผูกทรัพยากรเข้ากับอายุการใช้งานของตัวแปรบนสแต็ก (ตัวแปรโลคอลที่ประกาศในขอบเขตที่กำหนด): หาก เกิด ข้อยกเว้นขึ้น และมีการจัดการข้อยกเว้นอย่างเหมาะสม โค้ดที่จะถูกเรียกใช้งานเมื่อออกจากขอบเขต ปัจจุบัน จะมีเพียงตัวทำลาย (destructor) ของอ็อบเจ็กต์ที่ประกาศในขอบเขตนั้นเท่านั้น สุดท้าย ความใกล้เคียงกันของคำจำกัดความ (locality of definition) เกิดขึ้นได้จากการเขียนคำจำกัดความของตัวสร้าง (constructor) และตัวทำลาย (destructor) ไว้ติดกันในคำจำกัดความของคลาส

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

เมื่อเปรียบเทียบ RAII กับfinallyโครงสร้างที่ใช้ใน Java Stroustrup เขียนว่า “ในระบบจริง มีการได้มาซึ่งทรัพยากรมากกว่าประเภทของทรัพยากรมาก ดังนั้นเทคนิค 'การได้มาซึ่งทรัพยากรคือการเริ่มต้น' จึงทำให้มีโค้ดน้อยกว่าการใช้โครงสร้าง 'finally'” [ 1 ]

ในฐานะที่เป็นตัวแปรคงที่ของคลาส RAII ให้การรับประกันว่าอินสแตนซ์ของวัตถุที่ควรจะได้รับทรัพยากรนั้นได้รับจริง ซึ่งช่วยขจัดความจำเป็นในการใช้เมธอด "การตั้งค่า" เพิ่มเติมเพื่อให้วัตถุที่สร้างขึ้นใหม่พร้อมใช้งาน (งานทั้งหมดนี้ดำเนินการในตัวสร้าง ในทำนองเดียวกัน งาน "ปิดระบบ" เพื่อปล่อยทรัพยากรจะเกิดขึ้นในตัวทำลายของวัตถุ) และไม่จำเป็นต้องทดสอบอินสแตนซ์เพื่อตรวจสอบว่าได้รับการตั้งค่าอย่างถูกต้องก่อนการใช้งานทุกครั้ง[ 16 ]

การใช้งานทั่วไป

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

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

การควบคุม ความเป็นเจ้าของของอ็อบเจ็กต์ที่จัดสรรแบบไดนามิก (หน่วยความจำที่จัดสรรด้วยnewRAII ใน C++) สามารถทำได้ด้วย RAII เช่นกัน โดยที่อ็อบเจ็กต์จะถูกปล่อยเมื่ออ็อบเจ็กต์ RAII (แบบใช้สแต็ก) ถูกทำลาย เพื่อจุดประสงค์นี้ ไลบรารีมาตรฐาน C++11 ได้กำหนดคลาสตัวชี้อัจฉริยะstd::unique_ptrสำหรับอ็อบเจ็กต์ที่มีเจ้าของคนเดียวและstd::shared_ptrสำหรับอ็อบเจ็กต์ที่มีความเป็นเจ้าของร่วมกัน คลาสที่คล้ายกันนี้ยังมีให้ใช้งานstd::auto_ptrใน C++98 และboost::shared_ptrในไลบรารี Boostด้วย

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

กำจัดทิ้ง

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

ซี

สำหรับเวอร์ชันของ C ก่อนการแนะนำClangและGNU Compiler Collectionให้ใช้แอตทริบิวต์เป็นส่วนขยายที่ไม่เป็นมาตรฐานของ C [ 17 ]ต่อไปนี้เป็นคำอธิบายประกอบตัวแปรด้วยฟังก์ชันตัวทำลายที่กำหนดซึ่งจะถูกเรียกเมื่อตัวแปรอยู่นอกขอบเขต: defer[[gnu::cleanup]]

#include <stdio.h> #include <time.h>void writeLogFile () { const char * logFileName = "logfile.txt" ;[[ gnu :: cleanup ( fclosep )]] FILE * logFile = fopen ( logFileName , "w+" );time_t now = time ( NULL );fprintf ( logFile , "เริ่มบันทึกใน %s เวลา %s" , ชื่อไฟล์, ctime ( & ตอนนี้)); }

ในตัวอย่างนี้ คอมไพเลอร์จะจัดการให้fclosepมีการเรียกใช้ฟังก์ชันlogFileก่อนที่writeLogFileจะส่งค่ากลับ

ซี++

ในภาษา C++ การกำจัดออบเจ็กต์ทำได้โดยตรงด้วยดีสตรัคเตอร์ในภาษา C++ คลาสXจะเรียกดีสตรัคเตอร์ของตัวเองโดยอัตโนมัติ~X()เมื่อถึงจุดสิ้นสุดของขอบเขตการใช้งาน รูปแบบการกำจัดออบเจ็กต์ (Dispose pattern) นั้นเทียบเท่ากับ RAII ในภาษา C++ โดยพื้นฐานแล้ว

import std ;using std :: ifstream ; using std :: string ;void readFile () { if ( ifstream reader { "story.txt" }; reader ) { string line ; while ( std :: getline ( reader , line )) { std :: println ( "{}" , line ); } } else { std :: println ( stderr , "Failed to open file" ); } // reader ถูกทำลายหลังจากบล็อก if/else เสร็จสิ้น}

ซี#

ภาษา C#มีusingบล็อก `-with-resources` ซึ่งสามารถใช้ได้หากอ็อบเจ็กต์นั้นใช้งานอินเทอร์เฟซ `interface` System.IDisposableโดยจะเรียกDispose()เมธอด `with` เมื่อสิ้นสุดทรัพยากร

การใช้งานSystem ; การใช้งานSystem.IO ;เมื่อใช้( StreamReader reader = new StreamReader ( "story.txt" )) { string line ; while ( ( line = reader.ReadLine ( ) ) != null ) { Console.WriteLine ( line ); } } // reader จะถูกกำจัดโดยอัตโนมัติที่นี่

ชวา

Javaมีtryบล็อก `-with-resources` ซึ่งสามารถใช้ได้หากอ็อบเจ็กต์นั้นใช้งานอินเทอร์เฟซ `interface` java.lang.AutoCloseableโดยจะเรียกclose()เมธอด `with` เมื่อสิ้นสุดทรัพยากร

import java.io.BufferedReader ; import java.io.FileReader ; import java.io.IOException ;try ( BufferedReader reader = new BufferedReader ( new FileReader ( "story.txt" ))) { String line ; while (( line = reader . readLine ()) != null ) { System . out . println ( line ); } } catch ( IOException e ) { e . printStackTrace (); }

ไพธอน

Pythonมีwithบล็อกที่สามารถใช้งานได้หากอ็อบเจ็กต์นั้นใช้งานเมธอด__enter__และ__exit__อินเทอร์เฟซที่กำหนดไว้

with open ( "story.txt" , "r" ) as file : print ( file . readline ()) # พิมพ์บรรทัดแรกในไฟล์2

สิ่งนี้ยังใช้สำหรับการจัดการทรัพยากร เช่นกุญแจล็อคด้วย

จากthreading นำเข้าLockbalance_lock : Lock = Lock () with balance_lock : # ส่วนสำคัญ: อัปเดตยอดคงเหลือในบัญชีที่นี่...

สนิม

Rustอนุญาตให้กำหนดตรรกะการล้างข้อมูลแบบกำหนดเองได้ หากอ็อบเจ็กต์นั้นใช้งานอินเทอร์เฟซ `Internet` std::ops::Dropซึ่งจะเรียกdrop()เมธอด `cleanup` หลังจากที่อ็อบเจ็กต์นั้นออกจากขอบเขตการใช้งาน นอกจากนี้ยังสามารถเรียกเมธอดนี้ด้วยตนเองได้โดยใช้ ` std::mem::drop()ResourceContinuousError`

ข้อจำกัด

RAII ใช้ได้เฉพาะกับทรัพยากรที่ได้มาและปล่อย (โดยตรงหรือโดยอ้อม) โดยวัตถุที่จัดสรรบนสแต็ก ซึ่งมีอายุการใช้งานของวัตถุคงที่ที่กำหนดไว้อย่างดี วัตถุที่จัดสรร บนฮีปซึ่งได้มาและปล่อยทรัพยากรเองนั้นพบได้ทั่วไปในหลายภาษา รวมถึง C++ RAII ขึ้นอยู่กับวัตถุบนฮีปที่จะถูกลบโดยปริยายหรือโดยชัดแจ้งตลอดเส้นทางการทำงานที่เป็นไปได้ทั้งหมด เพื่อกระตุ้นตัวทำลายที่ปล่อยทรัพยากร (หรือเทียบเท่า) [ 18 ] : 8:27 สิ่งนี้สามารถทำได้โดยใช้ตัวชี้อัจฉริยะเพื่อจัดการวัตถุบนฮีปทั้งหมด โดยใช้ตัวชี้แบบอ่อนสำหรับวัตถุที่อ้างอิงแบบวนรอบ

ใน C++ การคลายสแต็กจะเกิดขึ้นได้ก็ต่อเมื่อมีการดักจับข้อยกเว้นที่ใดที่หนึ่งเท่านั้น เนื่องจาก "หากไม่พบตัวจัดการที่ตรงกันในโปรแกรม ฟังก์ชัน terminate() จะถูกเรียกใช้ ไม่ว่าสแต็กจะถูกคลายก่อนการเรียกใช้ terminate() นี้หรือไม่นั้นขึ้นอยู่กับการใช้งาน (15.5.1)" (มาตรฐาน C++03, §15.3/9) [ 19 ]พฤติกรรมนี้โดยทั่วไปยอมรับได้ เนื่องจากระบบปฏิบัติการจะปล่อยทรัพยากรที่เหลืออยู่ เช่น หน่วยความจำ ไฟล์ ซ็อกเก็ต ฯลฯ เมื่อโปรแกรมสิ้นสุดการทำงาน

ในการประชุม Gamelab ปี 2018 Jonathan Blowอ้างว่าการใช้ RAII อาจทำให้เกิดการแตกกระจายของหน่วยความจำซึ่งส่งผลให้เกิดแคชพลาด และส่งผลกระทบต่อ ประสิทธิภาพถึง 100 เท่าหรือมากกว่านั้น[ 20 ]

การนับอ้างอิง

Perl , Python (ใน การใช้งาน CPython ) [ 21 ] และPHP [ 22 ]จัดการอายุการใช้งานของวัตถุโดยการนับการอ้างอิงซึ่งทำให้สามารถใช้ RAII ได้ วัตถุที่ไม่มีการอ้างอิงอีกต่อไปจะถูกทำลายหรือทำให้เสร็จสิ้นและปล่อยทันที ดังนั้นตัวทำลายหรือตัวทำให้เสร็จสิ้นจึงสามารถปล่อยทรัพยากรได้ในเวลานั้น อย่างไรก็ตาม วิธีนี้ไม่ได้เป็นที่นิยมเสมอไปในภาษาดังกล่าว และโดยเฉพาะอย่างยิ่งไม่แนะนำให้ใช้ใน Python (โดยแนะนำให้ใช้ตัวจัดการบริบทและตัวทำให้เสร็จสิ้นจาก แพ็คเกจ weakref แทน )

อย่างไรก็ตาม อายุการใช้งานของวัตถุไม่จำเป็นต้องผูกติดกับขอบเขตใดๆ และวัตถุอาจถูกทำลายแบบไม่แน่นอนหรือไม่ถูกทำลายเลยก็ได้ ทำให้สามารถรั่วไหลทรัพยากรโดยไม่ได้ตั้งใจซึ่งควรจะถูกปล่อยเมื่อสิ้นสุดขอบเขตบางอย่าง วัตถุที่เก็บไว้ในตัวแปรคงที่ (โดยเฉพาะตัวแปรส่วนกลาง ) อาจไม่ได้รับการทำให้เสร็จสิ้นเมื่อโปรแกรมสิ้นสุด ดังนั้นทรัพยากรของวัตถุเหล่านั้นจึงไม่ได้รับการปล่อย CPython ไม่รับประกันว่าจะทำให้วัตถุเหล่านั้นเสร็จสิ้น ตัวอย่างเช่น นอกจากนี้ วัตถุที่มีการอ้างอิงแบบวนซ้ำจะไม่ถูกรวบรวมโดยตัวนับการอ้างอิงแบบง่าย และจะมีอายุยืนยาวอย่างไม่แน่นอน แม้ว่าจะถูกรวบรวม (โดยการรวบรวมขยะที่ซับซ้อนกว่า) เวลาและลำดับการทำลายก็จะไม่มีความแน่นอน ใน CPython มีตัวตรวจจับวงจรซึ่งตรวจจับวงจรและทำให้วัตถุในวงจรเสร็จสิ้น แม้ว่าก่อน CPython 3.4 วงจรจะไม่ถูกรวบรวมหากวัตถุใดๆ ในวงจรมีตัวทำให้เสร็จสิ้น[ 23 ]

ดูเพิ่มเติม

อ่านเพิ่มเติม

  • ตัวอย่างบท: " ข้อผิดพลาดที่ 67: การไม่ใช้กระบวนการจัดหาทรัพยากรคือการเริ่มต้น " โดย สตีเฟน ซี. ดิวเฮิร์สต์
  • บทสัมภาษณ์: " A Conversation with Bjarne Stroustrup " โดย Bill Venners
  • บทความ: " กฎของสองยักษ์ใหญ่ " โดย บียอร์น คาร์ลสัน และ แมทธิว วิลสัน
  • บทความ: " การนำแนวคิด 'การจัดหาทรัพยากรคือการเริ่มต้น' ไปใช้ " โดย แดนนี่ คาเลฟ
  • บทความ: " RAII, Dynamic Objects และ Factory ใน C++ " โดย Roland Pibinger
  • RAII ในเดลฟี: " RAII ในเดลฟีแบบบรรทัดเดียว " โดย แบร์รี เคลลี่
  • คู่มือ: RAII ในภาษา C++โดย W3computing
ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=Resource_acquisition_is_initialization&oldid=1352081053 "

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ การจัดหาทรัพยากรเป็นการเริ่มต้น

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

ตัวอย่างภาษา C++

ตัวอย่างต่อไปนี้แสดงวิธีการใช้งาน RAII สำหรับการเข้าถึงไฟล์และ การล็อก แบบมิวเท็กซ์ :

ประโยชน์

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

การใช้งานทั่วไป

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