ส่วนที่ 2 TClass Atom
ในหน่วย System.pas นั้น TClass ถูกกำหนดไว้ดังนี้:
TClass = คลาสของ TObject;
หมายความว่า TClass เป็นคลาสของ TObject เนื่องจาก TObject นั้นเป็นคลาส TClass จึงเป็นคลาสที่เรียกว่าคลาส
ตามแนวคิดแล้ว TClass เป็นคลาสประเภทหนึ่ง ซึ่งก็คือคลาส อย่างไรก็ตาม เรารู้ว่าคลาสของ DELPHI เป็นตัวแทนของข้อมูล VMT ดังนั้นคลาสจึงถือเป็นประเภทที่กำหนดไว้สำหรับรายการข้อมูล VMT จริงๆ แล้วคลาสนี้ถือเป็นประเภทตัวชี้ที่ชี้ไปยังข้อมูล VMT!
ในภาษา C++ แบบดั้งเดิมก่อนหน้านี้ ไม่สามารถกำหนดประเภทของคลาสได้ เมื่อคอมไพล์อ็อบเจ็กต์แล้ว จะได้รับการแก้ไข ข้อมูลโครงสร้างของคลาสจะถูกแปลงเป็นรหัสเครื่องสัมบูรณ์ และข้อมูลคลาสที่สมบูรณ์จะไม่มีอยู่ในหน่วยความจำ ภาษาเชิงวัตถุระดับสูงกว่าบางภาษาสามารถรองรับการเข้าถึงแบบไดนามิกและการเรียกใช้ข้อมูลคลาสได้ แต่มักต้องการกลไกการตีความภายในที่ซับซ้อนและทรัพยากรระบบที่มากขึ้น ภาษา Object Pascal ของ DELPHI ดูดซับคุณลักษณะที่ยอดเยี่ยมบางประการของภาษาเชิงวัตถุระดับสูง ในขณะที่ยังคงรักษาข้อได้เปรียบแบบดั้งเดิมของการคอมไพล์โปรแกรมลงในโค้ดเครื่องโดยตรง ซึ่งช่วยแก้ปัญหาฟังก์ชันขั้นสูงและประสิทธิภาพของโปรแกรมได้อย่างสมบูรณ์แบบ
เป็นเพราะ DELPHI เก็บข้อมูลคลาสที่สมบูรณ์ไว้ในแอปพลิเคชัน ซึ่งสามารถจัดเตรียมฟังก์ชันเชิงอ็อบเจ็กต์ขั้นสูง เช่น และ เพื่อแปลงและระบุคลาสในขณะรันไทม์ ซึ่งข้อมูล VMT ของคลาสมีบทบาทหลักที่สำคัญ เพื่อนที่สนใจสามารถอ่านกระบวนการประกอบทั้งสองของ AsClass และ IsClass ในหน่วยระบบ ซึ่งเป็นโค้ดการใช้งานของ as และเป็นตัวดำเนินการเพื่อเพิ่มความเข้าใจในคลาสและข้อมูล VMT ให้ลึกซึ้งยิ่งขึ้น
ด้วยประเภทของคลาส คุณสามารถใช้คลาสเป็นตัวแปรได้ ตัวแปรคลาสสามารถเข้าใจได้ว่าเป็นวัตถุพิเศษ และคุณสามารถเข้าถึงวิธีการของตัวแปรคลาสได้เหมือนกับวัตถุ ตัวอย่างเช่น: ลองมาดูที่ส่วนของโปรแกรมต่อไปนี้:
พิมพ์
TSampleClass = คลาสของ TSampleObject;
TSampleObject = คลาส ( TObject )
สาธารณะ
ตัวสร้าง สร้าง;
destructor ทำลายล้าง;
ฟังก์ชันคลาส GetSampleObjectCount:Integer;
กระบวนการ GetObjectIndex: จำนวนเต็ม;
จบ;
var
aSampleClass : TSampleClass;
aClass : TClass;
ในโค้ดนี้ เรากำหนดคลาส TSampleObject และประเภทคลาสที่เกี่ยวข้อง TSampleClass รวมถึงตัวแปรคลาสสองตัว aSampleClass และ aClass นอกจากนี้ เรายังกำหนด Constructor, destructor, วิธีการเรียน GetSampleObjectCount และวิธี object GetObjectIndex สำหรับคลาส TSampleObject
ก่อนอื่น มาทำความเข้าใจความหมายของตัวแปรคลาส aSampleClass และ aClass กันก่อน
แน่นอนว่า คุณสามารถถือว่า TSampleObject และ TObject เป็นค่าคงที่และกำหนดให้กับตัวแปร aClass ได้ เช่นเดียวกับการกำหนดค่าคงที่ 123 ค่าให้กับตัวแปรจำนวนเต็ม i ดังนั้นความสัมพันธ์ระหว่างประเภทคลาส คลาสและตัวแปรคลาสจึงเป็นความสัมพันธ์ระหว่างประเภท ค่าคงที่ และตัวแปร แต่อยู่ที่ระดับของคลาสมากกว่าระดับอ็อบเจ็กต์ แน่นอนว่าการกำหนด TObject ให้กับ aSampleClass โดยตรงนั้นไม่ถูกกฎหมาย เนื่องจาก aSampleClass เป็นตัวแปรคลาสของคลาส TSampleObject ที่ได้รับจาก TObject และ TObject ไม่มีคำจำกัดความทั้งหมดที่เข้ากันได้กับประเภท TSampleClass ในทางตรงกันข้าม การกำหนด TSampleObject ให้กับตัวแปร aClass ถือเป็นเรื่องถูกกฎหมาย เนื่องจาก TSampleObject เป็นคลาสที่ได้รับมาจาก TObject และเข้ากันได้กับประเภท TClass สิ่งนี้คล้ายกับความสัมพันธ์การกำหนดและประเภทการจับคู่ของตัวแปรออบเจ็กต์
ถ้าอย่างนั้น เรามาดูกันว่า class method คืออะไร
วิธีการที่เรียกว่าคลาสหมายถึงวิธีการที่เรียกว่าในระดับชั้นเรียน เช่นวิธีการ GetSampleObjectCount ที่กำหนดไว้ข้างต้น ซึ่งเป็นวิธีการประกาศด้วยคลาสคำที่สงวนไว้ วิธีการเรียนแตกต่างจากวิธีการของวัตถุที่ถูกเรียกในระดับวัตถุ วิธีการของวัตถุนั้นคุ้นเคยกับเราอยู่แล้ว และวิธีการของชั้นเรียนมักจะใช้ในระดับการเข้าถึงและการควบคุมลักษณะทั่วไปของวัตถุคลาสทั้งหมดและการจัดการวัตถุจากส่วนกลาง ในคำจำกัดความของ TObject เราสามารถค้นหาวิธีการเรียนได้จำนวนมาก เช่น ClassName, ClassInfo, NewInstance เป็นต้น ในหมู่พวกเขา NewInstance ยังถูกกำหนดให้เป็นเสมือน นั่นคือเมธอดคลาสเสมือน ซึ่งหมายความว่าคุณสามารถเขียนวิธีการปรับใช้ NewInstance ในคลาสย่อยที่ได้รับเพื่อสร้างอินสแตนซ์อ็อบเจ็กต์ของคลาสนั้นด้วยวิธีพิเศษได้
คุณยังสามารถใช้ตัวระบุ self ในเมธอดคลาสได้ แต่ความหมายของมันแตกต่างจาก self ในเมธอดอ็อบเจ็กต์ self ในเมธอดคลาสแสดงถึงคลาสของตัวเอง นั่นคือ ตัวชี้ไปยัง VMT ในขณะที่เมธอด self ในอ็อบเจ็กต์แสดงถึงตัวอ็อบเจ็กต์เอง นั่นคือ ตัวชี้ไปยังพื้นที่ข้อมูลอ็อบเจ็กต์ แม้ว่าเมธอดคลาสสามารถใช้ได้ในระดับคลาสเท่านั้น คุณยังคงสามารถเรียกเมธอดคลาสผ่านอ็อบเจ็กต์ได้ ตัวอย่างเช่น เมธอดคลาส ClassName ของอ็อบเจ็กต์ TObject สามารถเรียกผ่านคำสั่ง aObject.ClassName ได้ เนื่องจาก 4 ไบต์แรกในพื้นที่ข้อมูลอ็อบเจ็กต์ที่ชี้โดยตัวชี้อ็อบเจ็กต์คือตัวชี้ไปยังคลาส VMT ในทางตรงกันข้าม คุณไม่สามารถเรียกใช้วิธี object ในระดับชั้นเรียนได้ และคำสั่งเช่น TObject.Free จะต้องผิดกฎหมาย
เป็นที่น่าสังเกตว่า Constructor เป็นวิธีการเรียน และ destructor เป็นวิธีการแบบ object!
อะไร ตัวสร้างเป็นวิธีการของคลาสและตัวทำลายเป็นวิธีการของวัตถุ! มีข้อผิดพลาดอะไรบ้าง?
คุณจะเห็นว่าเมื่อคุณสร้างออบเจ็กต์ คุณใช้คำสั่งที่คล้ายกับข้อความต่อไปนี้อย่างชัดเจน:
aObject := TObject.Create;
เห็นได้ชัดว่าเรียกเมธอด Create ของคลาส TObject เมื่อลบวัตถุให้ใช้คำสั่งต่อไปนี้:
aObject.ทำลาย;
แม้ว่าคุณจะใช้วิธีการอิสระเพื่อปล่อยวัตถุ วิธีการทำลายของวัตถุจะถูกเรียกทางอ้อม
เหตุผลนั้นง่ายมาก ก่อนที่ object จะถูกสร้างขึ้น วัตถุนั้นยังไม่มีอยู่ มีเพียง class เท่านั้นที่มีอยู่เท่านั้น ในทางตรงกันข้าม การลบวัตถุจะต้องลบวัตถุที่มีอยู่ วัตถุนั้นถูกเผยแพร่ ไม่ใช่คลาส
สุดท้ายนี้ เรามาหารือเกี่ยวกับปัญหาของตัวสร้างที่สมมติขึ้นมา
ในภาษา C++ ดั้งเดิม สามารถใช้ตัวทำลายเสมือนได้ แต่การนำตัวสร้างเสมือนไปใช้นั้นเป็นปัญหาที่ยาก เพราะในภาษา C++ ดั้งเดิมไม่มีประเภทคลาส อินสแตนซ์ของออบเจ็กต์โกลบอลมีอยู่ในพื้นที่ข้อมูลโกลบอล ณ เวลาคอมไพล์ และออบเจ็กต์ในเครื่องของฟังก์ชันก็ถูกแมปในพื้นที่สแต็ก ณ เวลาคอมไพล์ แม้แต่ออบเจ็กต์ที่สร้างขึ้นแบบไดนามิกก็ยังถูกวางในโครงสร้างคลาสคงที่โดยใช้ตัวดำเนินการใหม่ พื้นที่ฮีปและตัวสร้างเป็นเพียงวิธีการวัตถุที่เริ่มต้นอินสแตนซ์วัตถุที่สร้างขึ้น ไม่มีเมธอดคลาสจริงในภาษา C++ ดั้งเดิม แม้ว่าสิ่งที่เรียกว่าเมธอดคลาสแบบสแตติกสามารถกำหนดได้ แต่ท้ายที่สุดแล้วเมธอดเหล่านั้นจะถูกนำไปใช้เป็นฟังก์ชันโกลบอลพิเศษ ไม่ต้องพูดถึงเมธอดคลาสเสมือนที่สามารถกำหนดเป้าหมายเฉพาะออบเจ็กต์เท่านั้น กรณีที่มีประสิทธิภาพ ดังนั้น ภาษา C++ ดั้งเดิมจึงเชื่อว่าก่อนที่จะสร้างอินสแตนซ์ออบเจ็กต์เฉพาะ เป็นไปไม่ได้ที่จะสร้างออบเจ็กต์เองตามออบเจ็กต์ที่จะสร้างขึ้น มันเป็นไปไม่ได้เลยจริงๆ เพราะสิ่งนี้จะสร้างความขัดแย้งที่ขัดแย้งในตัวเองในทางตรรกะ!
อย่างไรก็ตาม เป็นเพราะแนวคิดหลักของข้อมูลประเภทคลาสไดนามิก วิธีการคลาสเสมือนอย่างแท้จริง และตัวสร้างที่นำไปใช้ตามคลาสใน DELPHI ที่ทำให้ตัวสร้างเสมือนสามารถนำไปใช้ได้ วัตถุถูกสร้างขึ้นโดยชั้นเรียน วัตถุนั้นเปรียบเสมือนทารกที่กำลังเติบโต และชั้นเรียนก็คือแม่ของมันเอง ตัวทารกเองก็ไม่รู้ว่าเขาจะกลายเป็นคนแบบไหนในอนาคต แต่แม่ใช้วิธีการเรียนรู้ของตนเองเพื่อฝึกฝนลูกที่แตกต่างกัน . คนก็มีหลักการเหมือนกัน
มันอยู่ในคำจำกัดความของคลาส TComponent ที่ Constructor Create ถูกกำหนดให้เป็น virtual เพื่อให้การควบคุมประเภทต่างๆ สามารถใช้วิธีการก่อสร้างของตนเองได้ นี่คือความยิ่งใหญ่ของแนวคิด เช่น คลาสที่สร้างโดย TClass และความยิ่งใหญ่ของ DELPHI
-
บทที่ 3 มุมมองของเวลาและพื้นที่ใน WIN32
พ่อแก่ของฉันมองดูหลานชายตัวน้อยของเขากำลังเล่นของเล่นอยู่บนพื้น แล้วพูดกับฉันว่า "เด็กคนนี้ก็เหมือนกับคุณเมื่อตอนที่คุณยังเด็ก เขาชอบแยกของออกจากกันและหยุดหลังจากเห็นพวกมันจนจบเท่านั้น" เมื่อนึกถึงสมัยเด็กๆ ฉันมักจะรื้อรถของเล่น นาฬิกาปลุกเล็กๆ กล่องดนตรี ฯลฯ และมักถูกแม่ดุบ่อยๆ
ครั้งแรกที่ฉันเข้าใจหลักการพื้นฐานของคอมพิวเตอร์เกี่ยวกับกล่องดนตรีที่ฉันแยกออกมา มันอยู่ในหนังสือการ์ตูนตอนที่ฉันอยู่มัธยมปลาย ชายชรามีหนวดเคราสีขาวกำลังอธิบายทฤษฎีของเครื่องจักรอัจฉริยะ และลุงมีหนวดกำลังพูดถึงคอมพิวเตอร์และกล่องดนตรี พวกเขากล่าวว่าหน่วยประมวลผลกลางของคอมพิวเตอร์คือแถวของกกดนตรีที่ใช้สำหรับการออกเสียงในกล่องดนตรี และโปรแกรมคอมพิวเตอร์ก็คือก้อนที่อัดแน่นอยู่บนกระบอกเล็กในกล่องดนตรี การหมุนของกระบอกเล็กนั้นเทียบเท่ากัน ไปจนถึงการหมุนของหน่วยประมวลผลกลาง การเคลื่อนไหวตามธรรมชาติของตัวชี้คำสั่ง ในขณะที่ปุ่มที่แสดงถึงเสียงดนตรีบนกระบอกสูบขนาดเล็กจะควบคุมการสั่นสะเทือนของกกดนตรีเพื่อสร้างคำสั่งที่เทียบเท่ากับการทำงานของโปรแกรมโดยโปรเซสเซอร์กลาง กล่องดนตรีส่งเสียงทำนองอันไพเราะซึ่งเล่นตามโน้ตเพลงที่ช่างฝีมือสลักไว้บนกระบอกสูบขนาดเล็ก คอมพิวเตอร์จะประมวลผลที่ซับซ้อนตามโปรแกรมที่ตั้งโปรแกรมไว้ล่วงหน้าโดยโปรแกรมเมอร์ หลังจากที่ฉันเรียนมหาวิทยาลัย ฉันได้เรียนรู้ว่าชายชราที่มีหนวดเคราสีขาวคือทัวริงยักษ์ใหญ่ด้านวิทยาศาสตร์ ทฤษฎีไฟไนต์ออโตมาตาของเขาส่งเสริมการพัฒนาของการปฏิวัติข้อมูลทั้งหมด และลุงที่มีหนวดเป็นบิดาแห่งคอมพิวเตอร์ ฟอน นอยมันน์ สถาปัตยกรรมคอมพิวเตอร์ยังคงเป็นโครงสร้างสถาปัตยกรรมหลักของคอมพิวเตอร์ กล่องดนตรีไม่ได้ถูกรื้อออกโดยเปล่าประโยชน์ แม่ก็วางใจได้
ด้วยความเข้าใจที่เรียบง่ายและลึกซึ้งเท่านั้นที่เราสามารถสร้างการสร้างสรรค์ที่ลึกซึ้งและรัดกุมได้
ในบทนี้ เราจะพูดถึงแนวคิดพื้นฐานที่เกี่ยวข้องกับการเขียนโปรแกรมของเราในระบบปฏิบัติการ Windows 32 บิต และสร้างมุมมองเวลาและพื้นที่ที่ถูกต้องใน WIN32 ฉันหวังว่าหลังจากอ่านบทนี้แล้ว เราจะมีความเข้าใจอย่างลึกซึ้งยิ่งขึ้นเกี่ยวกับโปรแกรม กระบวนการ และเธรด เข้าใจหลักการของไฟล์ปฏิบัติการ ไลบรารีลิงก์แบบไดนามิกและแพ็คเกจรันไทม์ และเห็นความจริงเกี่ยวกับข้อมูลส่วนกลาง ข้อมูลในเครื่อง และพารามิเตอร์ในหน่วยความจำได้อย่างชัดเจน .
ส่วนที่ 1 การทำความเข้าใจกระบวนการ
เนื่องจากเหตุผลทางประวัติศาสตร์ Windows จึงมาจาก DOS ในยุคดอส เรามักจะมีแต่แนวคิดเรื่องโปรแกรม แต่ไม่มีแนวคิดเรื่องกระบวนการ ในเวลานั้น เฉพาะระบบปฏิบัติการทั่วไป เช่น UNIX และ VMS เท่านั้นที่มีแนวคิดเกี่ยวกับกระบวนการ และหลายกระบวนการหมายถึงมินิคอมพิวเตอร์ เทอร์มินัล และผู้ใช้หลายราย ซึ่งก็หมายถึงเงินด้วย โดยส่วนใหญ่ ฉันสามารถใช้ได้เฉพาะไมโครคอมพิวเตอร์และระบบ DOS ที่ค่อนข้างถูกเท่านั้น เมื่อฉันกำลังศึกษาระบบปฏิบัติการ ฉันเพิ่งเริ่มสัมผัสกับกระบวนการและมินิคอมพิวเตอร์
มันเป็นหลังจาก Windows 3 เท่านั้น ในอดีตภายใต้ DOS สามารถดำเนินการได้เพียงโปรแกรมเดียวในเวลาเดียวกัน แต่สำหรับ Windows สามารถดำเนินการได้หลายโปรแกรมพร้อมกัน ขณะรันโปรแกรมภายใต้ DOS โปรแกรมเดียวกันจะไม่สามารถดำเนินการพร้อมกันได้ แต่สำหรับ Windows โปรแกรมเดียวกันสามารถทำงานพร้อมกันได้มากกว่าสองชุด และแต่ละสำเนาของโปรแกรมที่ทำงานอยู่นั้นเป็นกระบวนการ เพื่อให้แม่นยำยิ่งขึ้น ทุก ๆ การรันโปรแกรมใด ๆ จะสร้างงาน และแต่ละงานก็คือกระบวนการ
เมื่อเข้าใจโปรแกรมและกระบวนการต่างๆ กัน คำว่า โปรแกรม ก็สามารถหมายถึงสิ่งที่คงที่ได้ โปรแกรมทั่วไปคือโค้ดคงที่และข้อมูลที่ประกอบด้วยไฟล์ EXE หรือไฟล์ EXE บวกกับไฟล์ DLL หลายไฟล์ กระบวนการคือการรันโปรแกรมซึ่งเป็นโค้ดและการเปลี่ยนแปลงข้อมูลที่รันแบบไดนามิกในหน่วยความจำ เมื่อจำเป็นต้องรันโปรแกรมแบบคงที่ ระบบปฏิบัติการจะจัดเตรียมพื้นที่หน่วยความจำบางส่วนสำหรับการดำเนินการนี้ ถ่ายโอนรหัสโปรแกรมและข้อมูลแบบคงที่ไปยังพื้นที่หน่วยความจำเหล่านี้ และเปลี่ยนตำแหน่งและแมปรหัสโปรแกรมและข้อมูลในพื้นที่นี้ ดำเนินการภายในจึงสร้างกระบวนการแบบไดนามิก
โปรแกรมเดียวกันที่ทำงานพร้อมกันสองชุดหมายความว่ามีพื้นที่กระบวนการสองช่องในหน่วยความจำระบบ แต่ฟังก์ชันของโปรแกรมเหมือนกัน แต่อยู่ในสถานะที่เปลี่ยนแปลงแบบไดนามิกต่างกัน
ในแง่ของระยะเวลาการทำงานของกระบวนการ แต่ละกระบวนการจะดำเนินการในเวลาเดียวกัน คำศัพท์ทางวิชาชีพเรียกว่าการดำเนินการแบบขนานหรือการดำเนินการพร้อมกัน แต่นี่เป็นความรู้สึกผิวเผินที่ระบบปฏิบัติการมอบให้เรา ที่จริงแล้ว แต่ละกระบวนการจะดำเนินการในลักษณะแบ่งเวลา กล่าวคือ แต่ละกระบวนการผลัดกันใช้เวลาของ CPU เพื่อดำเนินการคำสั่งโปรแกรมของกระบวนการ สำหรับ CPU คำสั่งของกระบวนการเดียวเท่านั้นที่จะดำเนินการในเวลาเดียวกัน ระบบปฏิบัติการเป็นตัวจัดการที่อยู่เบื้องหลังการทำงานของกระบวนการตามกำหนดเวลา โดยจะบันทึกและสลับสถานะปัจจุบันของแต่ละกระบวนการที่ดำเนินการใน CPU เพื่อให้แต่ละกระบวนการตามกำหนดเวลาคิดว่ากำลังทำงานอย่างสมบูรณ์และต่อเนื่อง เนื่องจากการกำหนดเวลาการแบ่งปันเวลาของกระบวนการต่างๆ นั้นรวดเร็วมาก จึงทำให้เรารู้สึกว่ากระบวนการทั้งหมดกำลังทำงานอยู่ในเวลาเดียวกัน ในความเป็นจริง การทำงานพร้อมกันอย่างแท้จริงเป็นไปได้เฉพาะในสภาพแวดล้อมฮาร์ดแวร์ที่มี CPU หลายตัวเท่านั้น เมื่อเราพูดถึงเธรดในภายหลัง เราจะพบว่าเธรดคือสิ่งที่ขับเคลื่อนกระบวนการอย่างแท้จริง และที่สำคัญกว่านั้นคือเธรดเหล่านี้ให้พื้นที่กระบวนการ
ในแง่ของพื้นที่ที่ถูกครอบครองโดยกระบวนการ แต่ละพื้นที่กระบวนการค่อนข้างเป็นอิสระ และแต่ละกระบวนการทำงานในพื้นที่อิสระของตัวเอง โปรแกรมมีทั้งพื้นที่โค้ดและพื้นที่ข้อมูล ทั้งโค้ดและข้อมูลใช้พื้นที่กระบวนการ Windows จัดสรรหน่วยความจำจริงสำหรับพื้นที่ข้อมูลที่แต่ละกระบวนการต้องการ และโดยทั่วไปจะใช้วิธีการแบ่งปันสำหรับพื้นที่โค้ด โดยแมปหนึ่งโค้ดของโปรแกรมกับหลายกระบวนการของโปรแกรม ซึ่งหมายความว่าหากโปรแกรมมีโค้ด 100K และต้องการพื้นที่ข้อมูล 100K ซึ่งหมายความว่าต้องใช้พื้นที่กระบวนการทั้งหมด 200K ระบบปฏิบัติการจะจัดสรรพื้นที่กระบวนการ 200K ในครั้งแรกที่รันโปรแกรม และ 200K ของกระบวนการ พื้นที่จะถูกจัดสรรเป็นครั้งที่สองที่รันโปรแกรม เมื่อกระบวนการเริ่มต้น ระบบปฏิบัติการจะจัดสรรพื้นที่ข้อมูลเพียง 100K เท่านั้น ในขณะที่พื้นที่รหัสแบ่งพื้นที่ของกระบวนการก่อนหน้า
ข้างต้นคือมุมมองเวลาและพื้นที่พื้นฐานของกระบวนการในระบบปฏิบัติการ Windows ที่จริงแล้ว มีความแตกต่างอย่างมากในมุมมองเวลาและพื้นที่ของกระบวนการระหว่างระบบปฏิบัติการ Windows 16 บิตและ 32 บิต
ในแง่ของเวลา การจัดการกระบวนการของระบบปฏิบัติการ Windows 16 บิต เช่น Windows 3.x นั้นง่ายมาก จริงๆ แล้วเป็นเพียงระบบปฏิบัติการการจัดการแบบหลายงาน นอกจากนี้ การกำหนดเวลางานของระบบปฏิบัติการเป็นแบบพาสซีฟ หากงานไม่ละทิ้งการประมวลผลข้อความ ระบบปฏิบัติการต้องรอ เนื่องจากข้อบกพร่องในการจัดการกระบวนการของระบบ Windows 16 บิต เมื่อกระบวนการทำงาน กระบวนการนั้นจะครอบครองทรัพยากรของ CPU โดยสมบูรณ์ ในสมัยนั้น เพื่อให้ Windows 16 บิตมีโอกาสกำหนดเวลางานอื่นๆ Microsoft ยกย่องนักพัฒนาแอปพลิเคชัน Windows ที่เป็นโปรแกรมเมอร์ที่มีใจกว้าง ดังนั้นพวกเขาจึงเต็มใจเขียนโค้ดเพิ่มอีกสองสามบรรทัดเพื่อมอบเป็นของขวัญ ระบบปฏิบัติการ ในทางตรงกันข้าม ระบบปฏิบัติการ WIN32 เช่น Windows 95 และ NT มีความสามารถของระบบปฏิบัติการแบบหลายกระบวนการและแบบมัลติทาสกิ้งอย่างแท้จริง กระบวนการใน WIN32 ได้รับการกำหนดเวลาโดยระบบปฏิบัติการอย่างสมบูรณ์ เมื่อการแบ่งเวลาของกระบวนการทำงานสิ้นสุดลง ระบบปฏิบัติการจะสลับไปยังกระบวนการถัดไปโดยไม่คำนึงว่ากระบวนการยังคงประมวลผลข้อมูลอยู่หรือไม่ พูดอย่างเคร่งครัดระบบปฏิบัติการ Windows 16 บิตไม่สามารถถือเป็นระบบปฏิบัติการที่สมบูรณ์ได้ แต่ระบบปฏิบัติการ WIN32 32 บิตเป็นระบบปฏิบัติการที่แท้จริง แน่นอนว่า Microsoft จะไม่บอกว่า WIN32 ชดเชยข้อบกพร่องของ Windows 16 บิต แต่อ้างว่า WIN32 ใช้เทคโนโลยีขั้นสูงที่เรียกว่า "การทำงานหลายอย่างพร้อมกันล่วงหน้า" ซึ่งเป็นวิธีการเชิงพาณิชย์
จากมุมมองของพื้นที่ แม้ว่าพื้นที่กระบวนการในระบบปฏิบัติการ Windows 16 บิตจะค่อนข้างเป็นอิสระ แต่กระบวนการต่างๆ ก็สามารถเข้าถึงพื้นที่ข้อมูลของกันและกันได้อย่างง่ายดาย เนื่องจากจริงๆ แล้วกระบวนการเหล่านี้เป็นเซ็กเมนต์ข้อมูลที่แตกต่างกันในพื้นที่ทางกายภาพเดียวกัน และการดำเนินการที่อยู่ที่ไม่เหมาะสมอาจทำให้การอ่านและการเขียนพื้นที่ไม่ถูกต้อง และทำให้ระบบปฏิบัติการเสียหายได้อย่างง่ายดาย อย่างไรก็ตาม ในระบบปฏิบัติการ WIN32 แต่ละพื้นที่กระบวนการจะเป็นอิสระอย่างสมบูรณ์ WIN32 จัดเตรียมแต่ละกระบวนการด้วยพื้นที่ที่อยู่เสมือนและต่อเนื่องสูงสุด 4G สิ่งที่เรียกว่าพื้นที่ที่อยู่ต่อเนื่องหมายความว่าแต่ละกระบวนการมีพื้นที่ที่อยู่ตั้งแต่ $00000000 ถึง $FFFFFFFF แทนที่จะเป็นพื้นที่แบ่งส่วนของ Windows 16 บิต ใน WIN32 คุณไม่ต้องกังวลว่าการดำเนินการอ่านและเขียนจะส่งผลต่อข้อมูลในพื้นที่กระบวนการอื่นโดยไม่ได้ตั้งใจ และไม่ต้องกังวลว่ากระบวนการอื่นจะมารบกวนงานของคุณ ในเวลาเดียวกัน พื้นที่เสมือน 4G ต่อเนื่องที่ WIN32 มอบให้สำหรับกระบวนการของคุณคือหน่วยความจำกายภาพที่ระบบปฏิบัติการแมปกับคุณโดยรองรับฮาร์ดแวร์ . หน่วยความจำทางกายภาพ
ส่วนที่ 2 พื้นที่กระบวนการ
เมื่อเราใช้ DELPHI เพื่อเขียนแอปพลิเคชัน WIN32 เราไม่ค่อยสนใจโลกภายในของกระบวนการเมื่อทำงาน เนื่องจาก WIN32 มอบพื้นที่กระบวนการเสมือนต่อเนื่อง 4G สำหรับกระบวนการของเรา บางทีแอปพลิเคชันที่ใหญ่ที่สุดในโลกอาจใช้เพียงบางส่วนเท่านั้นในปัจจุบัน ดูเหมือนว่าพื้นที่กระบวนการจะไม่จำกัด แต่พื้นที่กระบวนการ 4G นั้นเป็นเสมือน และหน่วยความจำที่แท้จริงของเครื่องของคุณอาจอยู่ไกลจากนี้ แม้ว่ากระบวนการจะมีพื้นที่กว้างใหญ่ แต่โปรแกรมอัลกอริธึมที่ซับซ้อนบางโปรแกรมก็ยังไม่สามารถทำงานได้เนื่องจากสแต็กโอเวอร์โฟลว์ โดยเฉพาะโปรแกรมที่มีอัลกอริธึมแบบเรียกซ้ำจำนวนมาก
ดังนั้นความเข้าใจเชิงลึกเกี่ยวกับโครงสร้างของพื้นที่กระบวนการ 4G ความสัมพันธ์กับหน่วยความจำกายภาพ ฯลฯ จะช่วยให้เราเข้าใจโลกแห่งอวกาศ-เวลาของ WIN32 ได้ชัดเจนยิ่งขึ้น เพื่อให้เราสามารถใช้วิธีการที่ถูกต้องในงานพัฒนาจริงได้ . โลกทัศน์และวิธีการแก้ไขปัญหายากๆ ต่างๆ
ต่อไป เราจะใช้การทดลองง่ายๆ เพื่อทำความเข้าใจโลกภายในของพื้นที่กระบวนการของ WIN32 อาจต้องมีความรู้เกี่ยวกับการลงทะเบียน CUP และภาษาแอสเซมบลีบ้าง แต่ฉันพยายามอธิบายเป็นภาษาง่ายๆ
เมื่อ DELPHI เริ่มต้น โครงการ Project1 จะถูกสร้างขึ้นโดยอัตโนมัติ และเราจะเริ่มต้นด้วยโครงการนั้น ตั้งค่าเบรกพอยต์ที่ใดก็ได้ในโปรแกรมต้นฉบับของ Project1.dpr เช่น ตั้งค่าเบรกพอยต์ที่ประโยคเริ่มต้น จากนั้นรันโปรแกรมและจะหยุดโดยอัตโนมัติเมื่อถึงจุดพัก ในขณะนี้ เราสามารถเปิดหน้าต่าง CPU ในเครื่องมือแก้ไขข้อบกพร่องเพื่อดูโครงสร้างภายในของพื้นที่กระบวนการได้
รีจิสเตอร์คำสั่งปัจจุบัน Eip หยุดที่ $0043E4B8 จากเลขฐานสิบหกสองตัวสูงสุดของที่อยู่ซึ่งคำสั่งโปรแกรมอยู่นั้นเป็นศูนย์ทั้งคู่ จะเห็นได้ว่าโปรแกรมปัจจุบันอยู่ที่ตำแหน่งที่อยู่ที่ด้านล่างของ 4G พื้นที่กระบวนการซึ่งใช้พื้นที่ $00000000 ถึงพื้นที่ที่อยู่ที่ค่อนข้างน้อยสำหรับ $FFFFFFFF
ในกล่องคำสั่งในหน้าต่าง CPU คุณสามารถดูเนื้อหาของพื้นที่กระบวนการได้ เมื่อดูเนื้อหาของพื้นที่น้อยกว่า $00400000 คุณจะพบชุดเครื่องหมายคำถาม "????" ปรากฏในเนื้อหาที่น้อยกว่า $00400000 นั่นเป็นเพราะพื้นที่ที่อยู่ไม่ได้รับการแมปกับพื้นที่จริง หากคุณดูค่าเลขฐานสิบหกของตัวแปรร่วม HInstance ในขณะนี้ คุณจะพบว่ามีค่าเท่ากับ $00400000 เช่นกัน แม้ว่า HInstance จะสะท้อนถึงหมายเลขอ้างอิงของอินสแตนซ์กระบวนการ แต่จริงๆ แล้ว มันเป็นค่าที่อยู่เริ่มต้นเมื่อโหลดโปรแกรมลงในหน่วยความจำใน Windows 16 บิตเช่นกัน ดังนั้นเราจึงสามารถคิดได้ว่าโปรแกรมของกระบวนการถูกโหลดเริ่มต้นที่ $00400000 นั่นคือพื้นที่เริ่มต้นที่ 4M ในพื้นที่เสมือน 4G คือพื้นที่ที่โหลดโปรแกรม
ตั้งแต่ $00400000 เป็นต้นไปและก่อน $0044D000 โดยส่วนใหญ่จะเป็นพื้นที่ที่อยู่ของโค้ดโปรแกรมและข้อมูลส่วนกลาง ในกล่องสแต็กในหน้าต่าง CPU คุณสามารถดูที่อยู่ของสแต็กปัจจุบันได้ ในทำนองเดียวกัน คุณจะพบว่าพื้นที่ที่อยู่สแต็กปัจจุบันอยู่ระหว่าง $0067B000 ถึง $00680000 โดยมีความยาว $5,000 ในความเป็นจริง ขนาดพื้นที่สแต็กขั้นต่ำของกระบวนการคือ 5,000 ดอลลาร์ ซึ่งได้มาจากค่าขนาดสแต็กขั้นต่ำที่ตั้งไว้ในหน้า Linker ของ ProjectOptions เมื่อคอมไพล์โปรแกรม DELPHI บวกด้วย 1,000 ดอลลาร์ สแต็กจะขยายจากที่อยู่ระดับสูงไปยังด้านล่าง เมื่อสแต็กเมื่อโปรแกรมทำงานไม่เพียงพอ ระบบจะเพิ่มขนาดของพื้นที่สแต็กไปยังที่อยู่ด้านล่างโดยอัตโนมัติ พื้นที่กระบวนการ เมื่อคอมไพล์โปรแกรม DELPHI คุณสามารถควบคุมพื้นที่สแต็กสูงสุดที่สามารถเพิ่มได้โดยการตั้งค่าขนาดสแต็กสูงสุดในหน้า Linker ใน ProjectOptions โดยเฉพาะอย่างยิ่งในโปรแกรมที่มีความสัมพันธ์การเรียกรูทีนย่อยเชิงลึก หรือใช้อัลกอริธึมแบบเรียกซ้ำ ค่าของขนาดสแต็กสูงสุดจะต้องตั้งค่าอย่างสมเหตุสมผล เนื่องจากการเรียกรูทีนย่อยต้องใช้พื้นที่สแต็ก และหลังจากที่สแต็กหมด ระบบจะทำให้เกิดข้อผิดพลาด "Stack overflow"
ดูเหมือนว่าพื้นที่กระบวนการหลังพื้นที่สแต็กควรเป็นพื้นที่ว่าง ในความเป็นจริง นี่ไม่ใช่กรณี ข้อมูลที่เกี่ยวข้องของ WIN32 บอกว่าพื้นที่ 2G หลังจาก 80,000,000 ดอลลาร์เป็นพื้นที่ที่ระบบใช้ ดูเหมือนว่ากระบวนการนี้สามารถเป็นเจ้าของพื้นที่ 2G ได้เท่านั้น ในความเป็นจริง พื้นที่ที่กระบวนการสามารถเป็นเจ้าของได้จริงๆ นั้นไม่ใช่พื้นที่ 2G ด้วยซ้ำ เนื่องจากพื้นที่ 4M ตั้งแต่ 00000000 ดอลลาร์สหรัฐฯ ถึง 00400000 ดอลลาร์สหรัฐฯ ก็เป็นพื้นที่จำกัดเช่นกัน
แต่ไม่ว่าอย่างไร ที่อยู่ที่กระบวนการของเราสามารถใช้ได้ก็ยังคงกว้างมาก โดยเฉพาะอย่างยิ่งหลังจากพื้นที่สแต็กและระหว่าง $80,000,000 นี่คือสนามรบหลักของพื้นที่กระบวนการ พื้นที่หน่วยความจำที่จัดสรรโดยกระบวนการจากระบบจะถูกแมปกับพื้นที่นี้ ไลบรารีลิงก์แบบไดนามิกที่โหลดโดยกระบวนการจะถูกแมปกับพื้นที่นี้ พื้นที่เธรดสแต็กของเธรดใหม่จะถูกแมปกับพื้นที่นี้ด้วย เกือบทั้งหมด การดำเนินการที่เกี่ยวข้องกับการจัดสรรหน่วยความจำทั้งหมดจะถูกแมปกับพื้นที่นี้ โปรดทราบว่าการแมปที่กล่าวถึงในที่นี้หมายถึงความสอดคล้องระหว่างหน่วยความจำจริงและพื้นที่เสมือนนี้ไม่สามารถใช้พื้นที่กระบวนการที่ไม่ได้แมปกับหน่วยความจำจริงได้ เช่นเดียวกับสตริงของ "" ในกล่องคำสั่งของหน้าต่าง CPU ในระหว่างการดีบัก ? ???"
-
ขอบคุณสำหรับการอ่าน!