สัญญาณ (Signals) คือการขัดจังหวะที่ส่งมายังโปรเซสโดยระบบปฏิบัติการ ซึ่งสามารถทำให้โปรแกรมจบก่อนเวลา สร้าง interrupt ได้โดยกด Ctrl+C บน UNIX, LINUX, Mac OS X หรือ Windows
มีสัญญาณที่โปรแกรมจับไม่ได้ แต่มีรายการสัญญาณต่อไปนี้ที่จับได้ในโปรแกรมและดำเนินการตามสัญญาณ สัญญาณเหล่านี้กำหนดใน header file ของ C++
| Signal | Description |
|---|---|
| SIGABRT | การจบโปรแกรมแบบผิดปกติ เช่น เรียก abort |
| SIGFPE | การดำเนินการคณิตศาสตร์ผิดพลาด เช่น หารศูนย์ หรือ overflow |
| SIGILL | ตรวจพบคำสั่งผิดกฎหมาย |
| SIGINT | ได้รับสัญญาณสนใจแบบโต้ตอบ (เช่น Ctrl+C) |
| SIGSEGV | การเข้าถึงหน่วยความจำไม่ถูกต้อง |
| SIGTERM | คำขอจบโปรแกรมที่ส่งมายังโปรแกรม |
ฟังก์ชัน signal()
ไลบรารีจัดการสัญญาณ C++ มีฟังก์ชัน signal เพื่อจับเหตุการณ์ไม่คาดคิด ไวยากรณ์:
void (*signal (int sig, void (*func)(int)))(int);
อย่างง่าย ฟังก์ชันนี้รับสองอาร์กิวเมนต์: อาร์กิวเมนต์แรกเป็น integer แทนหมายเลขสัญญาณ อาร์กิวเมนต์ที่สองเป็น pointer ไปยังฟังก์ชันจัดการสัญญาณ
ตัวอย่างจับสัญญาณ SIGINT ด้วย signal()
ตัวอย่าง
#include <iostream>
#include <csignal>
using namespace std;
void signalHandler(int signum) {
cout << "Interrupt signal (" << signum << ") received.\n";
// cleanup and close up stuff here
exit(signum);
}
int main() {
// ลงทะเบียนสัญญาณ SIGINT และ handler
signal(SIGINT, signalHandler);
while (1) {
cout << "Going to sleep...." << endl;
sleep(1);
}
return 0;
}
ผลลัพธ์
Going to sleep.... Going to sleep.... Going to sleep....
หลังกด Ctrl + C จะแสดง:
ผลลัพธ์
Going to sleep.... Going to sleep.... Going to sleep.... Interrupt signal (2) received.
ฟังก์ชัน raise()
สร้างสัญญาณได้ด้วย raise() ซึ่งรับหมายเลขสัญญาณ integer ไวยากรณ์:
int raise (signal sig);
sig คือหมายเลขสัญญาณ: SIGINT, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGTERM, SIGHUP ตัวอย่างสร้างสัญญาณภายในด้วย raise()
ตัวอย่าง
#include <iostream>
#include <csignal>
using namespace std;
void signalHandler(int signum) {
cout << "Interrupt signal (" << signum << ") received.\n";
exit(signum);
}
int main() {
int i = 0;
signal(SIGINT, signalHandler);
while (++i) {
cout << "Going to sleep...." << endl;
if (i == 3) {
raise(SIGINT);
}
sleep(1);
}
return 0;
}
ผลลัพธ์
Going to sleep.... Going to sleep.... Going to sleep.... Interrupt signal (2) received.