คลาสเธรดใน Delphi
Raptor[สตูดิโอจิต]
http://mental.mentu.com
(หนึ่ง)
มีคลาสเธรด TThread ใน Delphi ที่ใช้ในการดำเนินการการเขียนโปรแกรมแบบมัลติเธรด หนังสือ Delphi ส่วนใหญ่กล่าวถึงสิ่งนี้ แต่โดยพื้นฐานแล้วพวกเขาจะให้ข้อมูลเบื้องต้นสั้น ๆ เกี่ยวกับสมาชิกหลายคนของคลาส TThread แล้วอธิบายฟังก์ชันการดำเนินการ ของการซิงโครไนซ์เสร็จสมบูรณ์ อย่างไรก็ตาม นี่ไม่ใช่การเขียนโปรแกรมแบบมัลติเธรดทั้งหมด จุดประสงค์ของการเขียนบทความนี้คือเพื่อเสริมสิ่งนี้
เธรดเป็นส่วนสำคัญของโค้ดที่ทำงานพร้อมกันในกระบวนการ กระบวนการมีอย่างน้อยหนึ่งเธรด ที่เรียกว่าเธรดหลัก สามารถมีได้หลายเธรดย่อยในเวลาเดียวกัน เมื่อใช้มากกว่าหนึ่งเธรดในกระบวนการ จะเรียกว่า "มัลติเธรด"
แล้วสิ่งที่เรียกว่า "ชิ้นส่วนของรหัส" นี้ถูกกำหนดไว้อย่างไร? อันที่จริงมันเป็นฟังก์ชันหรือกระบวนการ (สำหรับ Delphi)
หากคุณใช้ Windows API เพื่อสร้างเธรด จะมีการปรับใช้ผ่านฟังก์ชัน API ที่เรียกว่า CreateThread ซึ่งถูกกำหนดเป็น:
จัดการ CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWord dwStackSize,
LPTHREAD_START_ROUTINE lpที่อยู่เริ่มต้น
LPVOID lpพารามิเตอร์
DWORD dwCreationFlags,
LPDWORD lpThreadId
-
พารามิเตอร์เป็นไปตามที่ชื่อกล่าวไว้: คุณลักษณะของเธรด (ใช้เพื่อตั้งค่าคุณลักษณะความปลอดภัยของเธรดภายใต้ NT, ไม่ถูกต้องภายใต้ 9X), ขนาดสแต็ก, ที่อยู่เริ่มต้น, พารามิเตอร์, แฟล็กการสร้าง (ใช้เพื่อตั้งค่าเธรด สถานะเมื่อสร้าง), รหัสเธรด และ ในที่สุดก็ส่งคืน Handle ของเธรด ที่อยู่เริ่มต้นคือทางเข้าสู่ฟังก์ชันเธรด จนกว่าฟังก์ชันเธรดจะสิ้นสุด เธรดจะสิ้นสุด
กระบวนการดำเนินการของเธรดทั้งหมดมีดังนี้:
เนื่องจาก CreateThread มีพารามิเตอร์มากมายและเป็น Windows API ฟังก์ชันเธรดทั่วไปจึงมีอยู่ใน C Runtime Library (ตามทฤษฎีแล้ว สามารถใช้งานได้ในระบบปฏิบัติการใดๆ ที่รองรับเธรด):
_beginthread แบบยาวที่ไม่ได้ลงนาม (เป็นโมฆะ (_USERENTRY *__start)(เป็นโมฆะ *), __stksize ที่ไม่ได้ลงนาม, เป็นโมฆะ *__arg);
Delphi ยังมีฟังก์ชันที่คล้ายกันซึ่งมีฟังก์ชันการทำงานเหมือนกัน:
ฟังก์ชั่น BeginThread (SecurityAttributes: Pointer; StackSize: LongWord; ThreadFunc: TThreadFunc; พารามิเตอร์: Pointer; CreationFlags: LongWord; var ThreadId: LongWord): จำนวนเต็ม;
ฟังก์ชันของทั้งสามฟังก์ชันนี้โดยพื้นฐานแล้วจะเหมือนกัน โดยทั้งหมดจะใส่โค้ดในฟังก์ชันเธรดลงในเธรดอิสระเพื่อดำเนินการ ความแตกต่างที่ใหญ่ที่สุดระหว่างฟังก์ชันเธรดและฟังก์ชันทั่วไปคือทันทีที่ฟังก์ชันเธรดเริ่มทำงาน ฟังก์ชันเริ่มต้นเธรดทั้งสามจะกลับมาทำงานอีกครั้ง เอาไปดำเนินการไหม เมื่อมันกลับมา เธรดหลักจะไม่สนใจและไม่รู้
ภายใต้สถานการณ์ปกติ หลังจากที่ฟังก์ชันเธรดกลับมา เธรดจะถูกยกเลิก แต่มีวิธีอื่น:
Windows API:
เป็นโมฆะ ExitThread (DWORD dwExitCode);
ไลบรารีรันไทม์ C:
เป็นโมฆะ _endthread (เป็นโมฆะ);
ไลบรารีรันไทม์ Delphi:
ขั้นตอน EndThread (รหัสทางออก: จำนวนเต็ม);
เพื่อบันทึกข้อมูลเธรดที่จำเป็น (สถานะ/คุณสมบัติ ฯลฯ) ระบบปฏิบัติการจะสร้างวัตถุภายในสำหรับเธรด ตัวอย่างเช่น ใน Windows หมายเลขอ้างอิงคือหมายเลขอ้างอิงของวัตถุภายในนี้ ดังนั้นวัตถุนี้จึงควรถูกปล่อยออกมา เมื่อเธรดสิ้นสุดลง
แม้ว่าการเขียนโปรแกรมแบบมัลติเธรดสามารถทำได้ง่ายโดยใช้ API หรือ RTL (Runtime Library) แต่ยังจำเป็นต้องมีการประมวลผลที่มีรายละเอียดมากขึ้น ด้วยเหตุนี้ Delphi จึงทำการห่อหุ้มเธรดในหน่วย Classes ให้ดีขึ้น นี่คือคลาสเธรด VCL: TThread
การใช้คลาสนี้ก็ง่ายมาก หนังสือ Delphi ส่วนใหญ่บอกว่าการใช้งานพื้นฐานคือ: ก่อนอื่นให้รับคลาสเธรดของคุณเองจาก TThread (เนื่องจาก TThread เป็นคลาสนามธรรมและไม่สามารถสร้างอินสแตนซ์ได้) จากนั้นใช้วิธี Override abstract: Execute( This คือฟังก์ชันเธรด ซึ่งเป็นส่วนหนึ่งของโค้ดที่ดำเนินการในเธรด) หากคุณต้องการใช้ออบเจ็กต์ Visual VCL คุณต้องดำเนินการผ่านกระบวนการซิงโครไนซ์ สำหรับรายละเอียดเฉพาะ เราจะไม่ลงรายละเอียดที่นี่ โปรดดูหนังสือที่เกี่ยวข้อง
สิ่งต่อไปที่บทความนี้จะกล่าวถึงคือวิธีที่คลาส TThread สรุปเธรด ซึ่งก็คือการศึกษาเชิงลึกเกี่ยวกับการใช้งานคลาส TThread เพราะเพียงแค่เข้าใจอย่างแท้จริงเท่านั้นเราจึงจะสามารถใช้งานได้ดีขึ้น
ต่อไปนี้เป็นการประกาศคลาส TThread ใน DELPHI7 (บทความนี้กล่าวถึงการใช้งานภายใต้แพลตฟอร์ม Windows เท่านั้น ดังนั้นโค้ดทั้งหมดที่เกี่ยวข้องกับแพลตฟอร์ม Linux จึงถูกลบออก):
TThread = คลาส
ส่วนตัว
FHandle: THandle;
FThreadID: THandle;
FCreateSuspended: บูลีน;
FTerminated: บูลีน;
FS ถูกระงับ: บูลีน;
FFreeOnTerminate: บูลีน;
เสร็จสิ้นแล้ว: บูลีน;
FReturnValue: จำนวนเต็ม;
FOnTerminate: TNotifyEvent;
FSynchronize: TSynchronizeRecord;
FFatalException: TObject;
ขั้นตอน CallOnTerminate;
ขั้นตอนคลาสซิงโครไนซ์ (ASyncRec: PSynchronizeRecord);
ฟังก์ชัน GetPriority: TThreadPriority;
ขั้นตอน SetPriority (ค่า: TThreadPriority);
ขั้นตอน SetSuspended (ค่า: บูลีน);
ได้รับการคุ้มครอง
ขั้นตอน CheckThreadError (รหัสข้อผิดพลาด: จำนวนเต็ม);
ขั้นตอน CheckThreadError (สำเร็จ: บูลีนเกิน);
ขั้นตอน DoTerminate;
ขั้นตอนการดำเนินการ เสมือน;
ขั้นตอนการซิงโครไนซ์ (วิธีการ: TThreadMethod);
คุณสมบัติ ReturnValue: จำนวนเต็มอ่าน FReturnValue เขียน FReturnValue;
คุณสมบัติสิ้นสุด: บูลีนอ่าน FTerminated;
สาธารณะ
ตัวสร้างสร้าง (CreateSuspended: Boolean);
destructor ทำลายล้าง;
ขั้นตอนหลังการก่อสร้าง;
ขั้นตอน ดำเนินการต่อ;
ขั้นตอนระงับ;
ขั้นตอน ยุติ;
ฟังก์ชั่น WaitFor: LongWord;
ขั้นตอนการเรียนประสาน (AThread: TThread; AMethod: TThreadMethod);
ขั้นตอนคลาส StaticSynchronize (AThread: TThread; Amethod: TThreadMethod);
คุณสมบัติ FatalException: TObject อ่าน FFatalException;
คุณสมบัติ FreeOnTerminate: บูลีนอ่าน FFreeOnTerminate เขียน FFreeOnTerminate;
คุณสมบัติจัดการ: THandle อ่าน FHandle;
ลำดับความสำคัญของคุณสมบัติ: TThreadPriority อ่าน GetPriority เขียน SetPriority;
คุณสมบัติถูกระงับ: บูลีนอ่าน FSuspended เขียน SetSuspended;
คุณสมบัติ ThreadID: THandle อ่าน FThreadID;
คุณสมบัติ OnTerminate: TNotifyEvent อ่าน FOnTerminate เขียน FOnTerminate;
จบ;
คลาส TThread เป็นคลาสที่ค่อนข้างเรียบง่ายใน RTL ของ Delphi มีคลาสไม่มากนัก และแอตทริบิวต์ของคลาสนั้นเรียบง่ายและชัดเจน บทความนี้จะดำเนินการวิเคราะห์โดยละเอียดของวิธีการสมาชิกของคลาสที่สำคัญอีกสองสามวิธีและเหตุการณ์เดียวเท่านั้น: OnTerminate .
(จะดำเนินต่อไป)