Penanganan Signal C++

Helo, para pemrogram yang berhasrat! Hari ini, kita akan menyelam ke dunia yang menarik tentang Penanganan Signal C++. Jangan khawatir jika anda baru mengenal pemrograman – saya akan memandu anda melalui ini langkah demi langkah, sama seperti yang saya lakukan untuk pelbagai pelajar selama tahun tahun pengajaran saya. Mari kita mulakan perjalanan ini bersama-sama!

C++ Signal Handling

Apa itu Signal?

Sebelum kita melompat ke detilnya, mari kita faham apa itu signal. Dalam dunia komputer, signal adalah seperti rakit penyiraman atau pemberitahuan kecil yang memberitahu program bahwa sesuatu yang penting telah berlaku. Ia serupa dengan cara telefon anda bergetar untuk memberitahu anda telah menerima mesej. Signal ini boleh dihantar oleh sistem operasi atau oleh program lain.

Fungsi signal()

Sekarang, mari kita bercakap tentang bintang pertama pertunjukan: fungsi signal(). Fungsi ini adalah seperti asisten pribadi untuk program anda. Ia membantu program anda untuk memutuskan apa yang perlu dilakukan apabila menerima signal tertentu.

Cara Menggunakan signal()

Inilah sintaksis dasar fungsi signal():

#include <csignal>

signal(signalNumber, signalHandler);

Mari kita pecahkan ini:

  • signalNumber: Ini adalah jenis signal yang kita minati.
  • signalHandler: Ini adalah fungsi yang akan dijalankan apabila signal diterima.

Contoh Sederhana

Mari lihat contoh sederhana untuk melihat bagaimana ini bekerja:

#include <iostream>
#include <csignal>

void signalHandler(int signum) {
std::cout << "Signal gangguan (" << signum << ") diterima.\n";
exit(signum);
}

int main() {
signal(SIGINT, signalHandler);

while(true) {
std::cout << "Program berjalan..." << std::endl;
sleep(1);
}

return 0;
}

Dalam contoh ini:

  1. Kita definisikan fungsi signalHandler yang mencetak pesan dan keluar dari program.
  2. Dalam main(), kita gunakan signal(SIGINT, signalHandler) untuk memberitahu program kita untuk menjalankan signalHandler apabila menerima signal SIGINT (biasanya dihantar apabila anda menekan Ctrl+C).
  3. Kita kemudian memiliki loop tak berakhir yang menjaga program berjalan.

Apabila anda menjalankan program ini dan menekan Ctrl+C, anda akan melihat pesan dari signalHandler sebelum program keluar.

Fungsi raise()

Sekarang, mari kita kenal bintang kedua: fungsi raise(). Jika signal() adalah seperti mengatur rakit penyiraman, raise() adalah seperti menekan tombol rakit penyiraman sendiri.

Cara Menggunakan raise()

Sintaksis untuk raise() lebih sederhana:

#include <csignal>

raise(signalNumber);

Di sini, signalNumber adalah jenis signal yang anda ingin kirim.

Contoh dengan raise()

Mari kitaubah contoh sebelumnya untuk menggunakan raise():

#include <iostream>
#include <csignal>

void signalHandler(int signum) {
std::cout << "Signal (" << signum << ") diterima.\n";
}

int main() {
signal(SIGTERM, signalHandler);

std::cout << "Menaikkan signal SIGTERM..." << std::endl;
raise(SIGTERM);

std::cout << "Kembali ke fungsi utama." << std::endl;

return 0;
}

Dalam contoh ini:

  1. Kita atur signalHandler untuk menangani signal SIGTERM.
  2. Dalam main(), kita gunakan raise(SIGTERM) untuk mengirim signal SIGTERM ke program kita sendiri.
  3. Ini memicu signalHandler, yang mencetak pesan.
  4. Setelah menangani signal, program terus berjalan dan mencetak pesan akhir.

Jenis Signal Umum

Mari lihat beberapa jenis signal umum yang mungkin anda temui:

Signal Keterangan
SIGABRT Pengakhiran tidak normal
SIGFPE Pengecualian titik lembur
SIGILL Instruksi tidak sah
SIGINT Gangguan CTRL+C
SIGSEGV Pelanggaran segmentasi
SIGTERM Permintaan pengakhiran

Praktik Terbaik dan Tips

  1. Berhati-hati dengan Variabel Global: Penangan signal harus berhati-hati apabila mengakses variabel global, karena mereka mungkin berada dalam keadaan inkonsisten.

  2. Jadilah Sederhana: Penangan signal harus seberapa mungkin sederhana. Operasi kompleks dalam penangan signal dapat menyebabkan perilaku yang tidak diharapkan.

  3. Gunakan volatile untuk Variabel Berbagi: Apabila anda memiliki variabel berbagi antara kode utama anda dan penangan signal, deklarasikan mereka sebagai volatile.

  4. Ingat, Signal adalah Asinkron: Signal boleh tiba pada waktu apapun, jadi desain program anda dengan ini diambil kira.

Contoh Lebih Lanjut

Mari kita gabungkan semuanya dengan contoh yang sedikit kompleks:

#include <iostream>
#include <csignal>
#include <unistd.h>

volatile sig_atomic_t gSignalStatus = 0;

void signalHandler(int signum) {
gSignalStatus = signum;
}

int main() {
// Daftarkan penangan signal
signal(SIGINT, signalHandler);
signal(SIGTERM, signalHandler);

std::cout << "Program dimulakan. Tekan Ctrl+C untuk mengganggu." << std::endl;

while(gSignalStatus == 0) {
std::cout << "Bekerja..." << std::endl;
sleep(1);
}

std::cout << "Signal " << gSignalStatus << " diterima. Membersihkan..." << std::endl;
// Lakukan pembersihan yang diperlukan di sini

return 0;
}

Dalam contoh ini:

  1. Kita gunakan variabel global gSignalStatus untuk melacak signal yang diterima.
  2. Kita mendaftarkan penangan untuk SIGINT dan SIGTERM.
  3. Program berjalan sampai signal diterima, kemudian melakukan pembersihan dan keluar.

Ini menunjukkan penggunaan penanganan signal yang lebih realistis dalam program yang perlu membersihkan sumber daya sebelum keluar.

Kesimpulan

Dan itu adalah, rakan-rakan! Kita telah melakukan perjalanan melalui wilayah Penanganan Signal C++, dari dasar-dasar signal() hingga yang proaktif raise(), dan juga menyentuh beberapa konsep yang lebih maju. Ingat, seperti belajar skill baru, menguasai penanganan signal memerlukan latihan. Jangan khuatir jika ia tidak klik segera – setiap pemrogram hebat dimulai persis di tempat anda sekarang.

Sebagai penutup, saya diingatkan oleh pelajar yang saya punya sekali yang kesusahan dengan konsep ini pada awalnya. Dia biasa mengatakan bahwa signal adalah seperti mencoba untuk menangkap rakun penyiraman yang tidak nampak. Tetapi dengan latihan dan kekuatan, dia tidak hanya menguasai konsep ini tetapi juga mengembangkan sistem penanganan kesalahan yang kuat untuk perisian perusahaan dia. Jadi teruskan, dan siapa tahu? Inovasi perisian yang伟大的 berikutnya mungkin hanya datang dari anda!

Selamat coding, dan may signal anda selalu ditangani dengan gracia!

Credits: Image by storyset