Kelas utas di Delphi
Raptor[Studio Mental]
http://mental.mentu.com
ketiga
Setelah membahas konstruktor, mari kita lihat destruktornya:
destruktor TThread.Destroy;
mulai
if (FThreadID <> 0) dan tidak selesai kemudian
mulai
Mengakhiri;
jika FCreateSuspended maka
Melanjutkan;
Tunggu;
akhir;
jika FHandle <> 0 maka CloseHandle(FHandle);
Kehancuran yang diwariskan;
FFatalException.Gratis;
HapusBenang;
akhir;
Sebelum objek thread dilepaskan, periksa terlebih dahulu apakah thread masih dieksekusi. Jika thread masih dieksekusi (ID thread bukan 0, dan flag akhir thread tidak disetel), proses Terminate dipanggil untuk mengakhiri thread. Proses Terminate hanya menyetel flag Terminated dari kelas thread, seperti pada kode berikut:
Prosedur TThread.Hentikan;
mulai
FDihentikan := Benar;
akhir;
Oleh karena itu, thread harus tetap terus dijalankan hingga berakhir secara normal, daripada langsung mengakhiri thread. Hal ini perlu diperhatikan.
Sedikit penyimpangan di sini: Banyak orang bertanya kepada saya bagaimana cara mengakhiri thread "segera" (tentu saja, mengacu pada thread yang dibuat dengan TThread). Tentu saja tidak berhasil! Satu-satunya cara untuk menghentikan thread adalah dengan membiarkan metode Execute menyelesaikan eksekusi, jadi secara umum, jika Anda ingin thread Anda dihentikan sesegera mungkin, Anda harus terus-menerus memeriksa tanda Terminated di metode Execute dalam jangka waktu singkat sehingga bahwa Anda dapat keluar tepat waktu. Ini adalah prinsip yang sangat penting ketika merancang kode berulir!
Tentu saja, jika Anda harus dapat keluar dari thread "segera", maka kelas TThread bukanlah pilihan yang baik, karena jika Anda menggunakan API untuk menghentikan thread secara paksa, objek thread TThread pada akhirnya tidak akan dirilis dengan benar, dan pelanggaran akses akan terjadi ketika objek dihancurkan. Dalam hal ini Anda hanya dapat menggunakan fungsi API atau RTL untuk membuat thread.
Jika thread dalam status startup-suspend, pindahkan thread ke status berjalan, lalu panggil WaitFor untuk menunggu hingga thread berakhir sebelum melanjutkan eksekusi. Implementasi WaitFor akan dijelaskan nanti.
Setelah utas berakhir, tutup Pegangan utas (Pegangan ada dalam pembuatan utas normal) dan lepaskan objek utas yang dibuat oleh sistem operasi.
Kemudian panggil TObject.Destroy untuk melepaskan objek ini dan melepaskan objek pengecualian yang tertangkap, dan terakhir panggil RemoveThread untuk mengurangi jumlah thread dalam proses.
Aspek lain mengenai Suspend/Resume dan pengaturan prioritas thread tidak menjadi fokus artikel ini dan tidak akan dibahas lagi. Apa yang akan dibahas di bawah ini adalah dua fokus lain dari artikel ini: Sinkronisasi dan WaitFor.
Namun sebelum memperkenalkan kedua fungsi ini, dua teknologi sinkronisasi thread lainnya perlu diperkenalkan: peristiwa dan bagian penting.
Event berbeda dengan event di Delphi. Intinya, Event setara dengan variabel Boolean global. Ini memiliki dua operasi penetapan: Setel dan Reset, yang setara dengan menyetelnya ke Benar atau Salah. Dan pengecekan nilainya dilakukan melalui operasi WaitFor. Sesuai dengan platform Windows, ada tiga fungsi API: SetEvent, ResetEvent, dan WaitForSingleObject (ada beberapa API yang mengimplementasikan fungsi WaitFor, ini yang paling sederhana).
Ketiganya primitif, sehingga Event dapat mengimplementasikan aplikasi dalam multi-thread yang tidak bisa dilakukan oleh variabel Boolean umum. Fungsi Set dan Reset telah disebutkan sebelumnya. Sekarang mari kita bicara tentang fungsi WaitFor:
Fungsi WaitFor adalah untuk memeriksa apakah status Acara adalah status Set (setara dengan True). Jika demikian, ia akan segera kembali thread yang memanggil WaitFor berada dalam status ditangguhkan. Selain itu, WaitFor memiliki parameter untuk pengaturan batas waktu. Jika parameter ini adalah 0, ia tidak akan menunggu dan segera mengembalikan status Peristiwa. Jika nilainya INFINITE, ia akan menunggu tanpa batas waktu hingga status Set terjadi menunggu jumlah milidetik yang sesuai. Kemudian kembalikan status Acara.
Ketika Peristiwa bertransisi dari status Reset ke status Set, maka akan membangunkan thread lain yang ditangguhkan karena peristiwa WaitFor. Inilah sebabnya mengapa disebut Peristiwa. Yang disebut "peristiwa" mengacu pada "transisi keadaan". Informasi "transisi keadaan" ini dapat diteruskan antar thread melalui Acara.
Tentu saja, fungsi serupa juga dapat dicapai dengan menggunakan variabel Boolean yang dilindungi (lihat pengenalan bagian penting di bawah), selama WaitFor diganti dengan loop kode yang memeriksa nilai Boolean. Secara fungsional tidak ada masalah sama sekali, namun dalam penggunaan sebenarnya Anda akan menemukan bahwa menunggu seperti itu akan menyita banyak sumber daya CPU, menurunkan kinerja sistem, dan mempengaruhi kecepatan eksekusi thread lain, sehingga tidak ekonomis dan bahkan terkadang mungkin terjadi. masalah. Jadi tidak disarankan menggunakan cara ini.
(bersambung)