อ่าน 5 นาที
ทึก
ใน การเขียนโปรแกรมคอมพิวเตอร์ thunk คือ ซับรูทีน ที่ใช้แทรกการคำนวณเข้าไปในซับรูทีนอื่น โดยหลักแล้ว thunk ใช้เพื่อหน่วงเวลาการคำนวณจนกว่าจะต้องการผลลัพธ์...
ทึก
ในการเขียนโปรแกรมคอมพิวเตอร์ thunk คือซับรูทีนที่ใช้แทรกการคำนวณเข้าไปในซับรูทีนอื่น โดยหลักแล้ว thunk ใช้เพื่อหน่วงเวลาการคำนวณจนกว่าจะต้องการผลลัพธ์ หรือเพื่อแทรกการดำเนินการที่ต้นหรือท้ายของซับรูทีนอื่น นอกจากนี้ยังมีแอปพลิเคชันอื่นๆ อีกมากมายในการสร้างโค้ดคอมไพเลอร์และการเขียนโปรแกรมแบบโมดูลาร์
คำนี้มีต้นกำเนิดมาจาก รูปแบบ ที่แปลกประหลาดของคำกริยาthinkโดยอ้างอิงถึงการใช้ thunks ดั้งเดิมใน คอมไพเลอร์ ALGOL 60ซึ่งต้องใช้การวิเคราะห์พิเศษ (thought) เพื่อกำหนดประเภทของรูทีนที่จะสร้าง[ 1 ] [ 2 ]
พื้นหลัง
ในช่วงแรกของ การวิจัย คอมไพเลอร์มีการทดลองอย่างกว้างขวางเกี่ยวกับกลยุทธ์การประเมินผล ที่แตกต่างกัน คำถามสำคัญคือ จะคอมไพล์การเรียกใช้ซับรูทีนอย่างไร หากอาร์กิวเมนต์สามารถเป็นนิพจน์ทางคณิตศาสตร์ใดๆ ก็ได้ แทนที่จะเป็นค่าคงที่ วิธีหนึ่งที่เรียกว่า " การเรียกใช้โดยค่า" ( call by value ) จะคำนวณอาร์กิวเมนต์ทั้งหมดก่อนการเรียกใช้ แล้วส่งค่าที่ได้ไปยังซับรูทีน ในขณะที่อีกวิธีหนึ่งคือ " การเรียกใช้โดยชื่อ" (call by name ) ซับรูทีนจะได้รับนิพจน์อาร์กิวเมนต์ที่ยังไม่ได้ประเมิน และต้องประเมินนิพจน์นั้นเอง
การใช้งาน "เรียกตามชื่อ" แบบง่ายๆ อาจแทนที่โค้ดของนิพจน์อาร์กิวเมนต์ด้วยการปรากฏแต่ละครั้งของพารามิเตอร์ที่เกี่ยวข้องในซับรูทีน แต่วิธีนี้อาจทำให้เกิดซับรูทีนหลายเวอร์ชันและโค้ดนิพจน์หลายชุด เพื่อเป็นการปรับปรุง คอมไพเลอร์สามารถสร้างซับรูทีนตัวช่วยที่เรียกว่าthunkซึ่งคำนวณค่าของอาร์กิวเมนต์ จากนั้นที่อยู่และสภาพแวดล้อม[ a ]ของซับรูทีนตัวช่วยนี้จะถูกส่งไปยังซับรูทีนดั้งเดิมแทนที่อาร์กิวเมนต์ดั้งเดิม ซึ่งสามารถเรียกได้หลายครั้งตามต้องการ ปีเตอร์ อิงเกอร์แมน อธิบาย thunk เป็นครั้งแรกโดยอ้างอิงถึงภาษาการเขียนโปรแกรม ALGOL 60 ซึ่งรองรับการประเมินแบบเรียกตามชื่อ[ 4 ]
แอปพลิเคชัน
การเขียนโปรแกรมเชิงฟังก์ชัน
แม้ว่าอุตสาหกรรมซอฟต์แวร์ส่วนใหญ่จะกำหนดมาตรฐาน การประเมินแบบเรียกตามค่าและเรียกตามการอ้างอิงแล้ว ก็ตาม [ 5 ]แต่การศึกษาอย่างจริงจังเกี่ยวกับการประเมินแบบเรียกตามชื่อยังคงดำเนินต่อไปใน ชุมชน การเขียนโปรแกรมเชิงฟังก์ชัน งานวิจัยนี้ได้สร้าง ภาษาโปรแกรมแบบ ประเมินแบบขี้เกียจ ขึ้นมา หลายภาษา โดยที่การประเมินแบบเรียกตามชื่อในรูปแบบต่างๆ ถือเป็นกลยุทธ์การประเมินมาตรฐาน คอมไพเลอร์สำหรับภาษาเหล่านี้ เช่นGlasgow Haskell Compilerได้พึ่งพา thunks อย่างมาก โดยมีคุณสมบัติเพิ่มเติมคือ thunks จะบันทึกผลลัพธ์เริ่มต้นไว้เพื่อหลีกเลี่ยงการคำนวณซ้ำ[ 6 ]ซึ่งเรียกว่าmemoizationหรือcall-by- need
ภาษาการเขียนโปรแกรมเชิงฟังก์ชันยังอนุญาตให้โปรแกรมเมอร์สร้าง thunk ได้อย่างชัดเจน โดยทำในซอร์สโค้ดด้วยการห่อนิพจน์อาร์กิวเมนต์ไว้ในฟังก์ชันนิรนามที่ไม่มีพารามิเตอร์ของตัวเอง ซึ่งจะป้องกันไม่ให้นิพจน์ถูกประเมินจนกว่าฟังก์ชันที่รับจะเรียกฟังก์ชันนิรนามนั้น ทำให้ได้ผลลัพธ์เช่นเดียวกับการเรียกตามชื่อ[ 7 ]การนำฟังก์ชันนิรนามมาใช้ในภาษาการเขียนโปรแกรมอื่นๆ ทำให้ความสามารถนี้แพร่หลายมากขึ้น
การเขียนโปรแกรมเชิงวัตถุ
Thunks มีประโยชน์ในแพลตฟอร์มการเขียนโปรแกรมเชิงวัตถุ ที่อนุญาตให้ คลาสสืบทอดอินเทอร์เฟซได้หลายรายการซึ่งนำไปสู่สถานการณ์ที่ อาจมีการเรียกใช้ เมธอด เดียวกัน ผ่านอินเทอร์เฟซหลายรายการ โค้ดต่อไปนี้แสดงให้เห็นสถานการณ์ดังกล่าวในภาษาC ++
คลาสA { public : virtual int Access () const { return value_ ; }ส่วนตัว: ค่าint_ ; };คลาสB { public : virtual int Access () const { return value_ ; }ส่วนตัว: ค่าint_ ; };คลาสC : สาธารณะA , สาธารณะB { สาธารณะ: int Access () const override { return better_value_ ; }ส่วนตัว: int better_value_ ; };int use ( B * b ) { return b -> Access (); }int main () { // ... B some_b ; use ( & some_b ); C some_c ; use ( & some_c ); }ในตัวอย่างนี้ โค้ดที่สร้างขึ้นสำหรับแต่ละคลาส A, B และ C จะมีตารางการเรียกใช้ฟังก์ชันที่สามารถใช้เรียกAccessวัตถุประเภทนั้นได้ โดยผ่านการอ้างอิงที่มีประเภทเดียวกัน คลาส C จะมีตารางการเรียกใช้ฟังก์ชันเพิ่มเติม ซึ่งใช้เรียกAccessวัตถุประเภท C ผ่านการอ้างอิงประเภท B นิพจน์b->Access()จะใช้ตารางการเรียกใช้ฟังก์ชันของ B เองหรือตาราง C เพิ่มเติม ขึ้นอยู่กับประเภทของวัตถุที่ b อ้างถึง หากอ้างถึงวัตถุประเภท C คอมไพเลอร์ต้องตรวจสอบให้แน่ใจว่าAccessการใช้งานของ C ได้รับที่อยู่ของอินสแตนซ์สำหรับวัตถุ C ทั้งหมด แทนที่จะเป็นส่วน B ที่สืบทอดมาของวัตถุนั้น[ 8 ]
เพื่อแก้ปัญหาการปรับค่าตัวชี้โดยตรง คอมไพเลอร์สามารถใส่ค่าชดเชยจำนวนเต็มลงในแต่ละรายการของตารางการเรียกใช้ฟังก์ชันได้ ค่าชดเชยนี้คือผลต่างระหว่างที่อยู่ของตัวอ้างอิงและที่อยู่ที่จำเป็นสำหรับการใช้งานเมธอด จากนั้นโค้ดที่สร้างขึ้นสำหรับการเรียกใช้แต่ละครั้งผ่านตารางการเรียกใช้ฟังก์ชันเหล่านี้จะต้องดึงค่าชดเชยและใช้เพื่อปรับที่อยู่ของอินสแตนซ์ก่อนที่จะเรียกใช้เมธอด
วิธีแก้ปัญหาที่เพิ่งอธิบายไปนั้นมีปัญหาคล้ายกับการใช้งาน call-by-name แบบง่ายๆ ที่อธิบายไว้ก่อนหน้านี้: คอมไพเลอร์สร้างโค้ดหลายชุดเพื่อคำนวณอาร์กิวเมนต์ (ที่อยู่ของอินสแตนซ์) ในขณะเดียวกันก็เพิ่มขนาดตารางการส่งคำสั่งเพื่อเก็บค่าออฟเซ็ต ทางเลือกอื่นคือ คอมไพเลอร์สามารถสร้างthunk ตัวปรับพร้อมกับการใช้งานของ C Accessที่ปรับที่อยู่ของอินสแตนซ์ตามจำนวนที่ต้องการแล้วจึงเรียกเมธอด thunk สามารถปรากฏในตารางการส่งคำสั่งของ C สำหรับ B ซึ่งจะช่วยขจัดความจำเป็นที่ผู้เรียกจะต้องปรับที่อยู่ด้วยตนเอง[ 9 ]
ความสามารถในการทำงานร่วมกัน
Thunk ถูกนำมาใช้กันอย่างแพร่หลายเพื่อให้ซอฟต์แวร์โมดูลต่างๆ สามารถทำงานร่วมกันได้ แม้ว่ารูทีนเหล่านั้นจะไม่สามารถเรียกกันได้โดยตรงก็ตาม ปัญหานี้อาจเกิดขึ้นเนื่องจากรูทีนเหล่านั้นมีข้อกำหนดการเรียก ที่แตกต่างกัน ทำงานในโหมด CPUหรือพื้นที่หน่วยความจำ ที่แตกต่างกัน หรืออย่างน้อยที่สุด รูทีนหนึ่งทำงานในเครื่องเสมือนคอมไพเลอร์ (หรือเครื่องมืออื่นๆ) สามารถแก้ปัญหานี้ได้โดยการสร้าง thunk ที่จะทำงานอัตโนมัติในขั้นตอนเพิ่มเติมที่จำเป็นในการเรียกรูทีนเป้าหมาย ไม่ว่าจะเป็นการแปลงอาร์กิวเมนต์ การคัดลอกไปยังตำแหน่งอื่น หรือการเปลี่ยนโหมด CPU thunk ที่ประสบความสำเร็จจะช่วยลดงานเพิ่มเติมที่ผู้เรียกต้องทำเมื่อเทียบกับการเรียกแบบปกติ
วรรณกรรมส่วนใหญ่เกี่ยวกับ thunks ที่สามารถทำงานร่วมกันได้นั้นเกี่ยวข้องกับแพลตฟอร์มWintel ต่างๆ รวมถึง MS-DOS , OS/2 , [ 10 ] Windows [ 11 ] [ 12 ] [ 13 ] [ 14 ]และ.NETและการเปลี่ยนจาก การกำหนดแอดเดรสหน่วยความจำ 16 บิตเป็น32 บิตเนื่องจากลูกค้าได้ย้ายจากแพลตฟอร์มหนึ่งไปยังอีกแพลตฟอร์มหนึ่ง thunks จึงมีความสำคัญอย่างยิ่งในการสนับสนุนซอฟต์แวร์รุ่นเก่าที่เขียนขึ้นสำหรับแพลตฟอร์มรุ่นเก่าUEFI CSMเป็นอีกตัวอย่างหนึ่งของการใช้ thunk สำหรับบูตโหลดเดอร์รุ่น เก่า
การเปลี่ยนจากโค้ด 32 บิตเป็น 64 บิตบน x86 ยังใช้รูปแบบ thunking ( WoW64 ) ด้วย อย่างไรก็ตาม เนื่องจากพื้นที่แอดเดรสของ x86-64 มีขนาดใหญ่กว่าพื้นที่แอดเดรสที่มีให้สำหรับโค้ด 32 บิต กลไก "thunk ทั่วไป" แบบเก่าจึงไม่สามารถใช้เรียกโค้ด 64 บิตจากโค้ด 32 บิตได้[ 15 ]กรณีเดียวที่โค้ด 32 บิตเรียกโค้ด 64 บิตคือใน thunking ของ WoW64 สำหรับ Windows API ไปยัง 32 บิต
การซ้อนทับและการเชื่อมโยงแบบไดนามิก
ในระบบที่ไม่มี ฮาร์ดแวร์ หน่วยความจำเสมือน อัตโนมัติ thunks สามารถใช้งานหน่วยความจำเสมือนแบบจำกัดที่เรียกว่าoverlays ได้ด้วย overlays นักพัฒนาจะแบ่งโค้ดของโปรแกรมออกเป็นส่วนๆ ที่สามารถโหลดและยกเลิกการโหลดได้อย่างอิสระ และระบุจุดเริ่มต้นในแต่ละส่วน ส่วนที่เรียกไปยังส่วนอื่นจะต้องทำโดยอ้อมผ่านตารางสาขาเมื่อส่วนใดส่วนหนึ่งอยู่ในหน่วยความจำ รายการในตารางสาขาของส่วนนั้นจะกระโดดเข้าไปในส่วนนั้น เมื่อส่วนใดส่วนหนึ่งถูกยกเลิกการโหลด รายการในนั้นจะถูกแทนที่ด้วย "reload thunks" ที่สามารถโหลดส่วนนั้นใหม่ได้ตามต้องการ[ 16 ]
ในทำนองเดียวกัน ระบบที่เชื่อมโยงโมดูลของโปรแกรมเข้าด้วยกันแบบไดนามิกในระหว่างการทำงานสามารถใช้ thunks เพื่อเชื่อมต่อโมดูลได้ แต่ละโมดูลสามารถเรียกโมดูลอื่น ๆ ผ่านตาราง thunks ที่ตัวเชื่อมโยงจะเติมเมื่อโหลดโมดูล ด้วยวิธีนี้ โมดูลต่างๆ สามารถโต้ตอบกันได้โดยไม่ต้องรู้ตำแหน่งในหน่วยความจำล่วงหน้า[ 17 ]
ดูเพิ่มเติม
เทคโนโลยีธันก์
- อินเทอร์เฟซโหมดป้องกัน DOS (DPMI)
- บริการโหมดป้องกัน DOS (DPMS)
- เจ/ไดเร็กต์
- เลเยอร์ของ Microsoft สำหรับ Unicode
- บริการเรียกใช้แพลตฟอร์ม
- Win32s
- วินโดวส์บนวินโดวส์
- โมดูลสนับสนุนความเข้ากันได้
- WoW64
- libffi
- ไวน์ (ตั้งแต่เวอร์ชัน 9.0) [ 18 ]
แนวคิดที่เกี่ยวข้อง
- ฟังก์ชันนิรนาม
- อนาคตและคำสัญญา
- การเรียกใช้ฟังก์ชันระยะไกล
- ชิม (การคำนวณ)
- แทรมโพลีน (คอมพิวเตอร์)
- การแสดงออกที่ลดลง
หมายเหตุ
สรุปเนื้อหา
ข้อมูลสำคัญจากบทความ
ข้อมูลสำคัญเกี่ยวกับ ทึก
ใน การเขียนโปรแกรมคอมพิวเตอร์ thunk คือ ซับรูทีน ที่ใช้แทรกการคำนวณเข้าไปในซับรูทีนอื่น โดยหลักแล้ว thunk ใช้เพื่อหน่วงเวลาการคำนวณจนกว่าจะต้องการผลลัพธ์...
พื้นหลัง
ในช่วงแรกของ การวิจัย คอมไพเลอร์ มีการทดลองอย่างกว้างขวางเกี่ยวกับ กลยุทธ์การประเมินผล ที่แตกต่างกัน คำถามสำคัญคือ จะคอมไพล์การเรียกใช้ซับรูทีนอย่างไร หากอาร์กิวเมนต์สามารถเป็นนิพจน์ทางคณิตศาสตร์ใดๆ ก็ได้ แทนที่จะเป็นค่าคงที่ วิธีหนึ่งที่เรียกว่า "...
การเขียนโปรแกรมเชิงฟังก์ชัน
แม้ว่าอุตสาหกรรมซอฟต์แวร์ส่วนใหญ่จะกำหนดมาตรฐาน การประเมินแบบเรียกตามค่าและ เรียกตามการอ้างอิงแล้ว ก็ตาม [ 5 ] แต่การศึกษาอย่างจริงจังเกี่ยวกับการประเมินแบบเรียกตามชื่อยังคงดำเนินต่อไปใน ชุมชน การเขียนโปรแกรมเชิงฟังก์ชัน งาน วิจัยนี้ได้สร้าง ภาษาโปรแกรมแบบ...
การเขียนโปรแกรมเชิงวัตถุ
Thunks มีประโยชน์ในแพลตฟอร์ม การเขียนโปรแกรมเชิงวัตถุ ที่อนุญาตให้ คลาส สืบทอด อินเทอร์เฟซได้หลายรายการ ซึ่งนำไปสู่สถานการณ์ที่ อาจมีการเรียกใช้ เมธอด เดียวกัน ผ่านอินเทอร์เฟซหลายรายการ โค้ดต่อไปนี้แสดงให้เห็นสถานการณ์ดังกล่าวในภาษา C ++