สัญญาณ
การแจ้งเตือนแบบอะซิงโครนัส
สัญญาณ เป็นบทเรียน C Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C Academy มีบทเรียนทั้งหมด 4 บทเรียน
สัญญาณคืออะไร
สัญญาณคือการแจ้งเตือนแบบอะซิงโครนัสที่ส่งไปยังกระบวนการเพื่อบอกว่าเกิดเหตุการณ์ขึ้น เช่น ผู้ใช้กด Ctrl-C หรือกระบวนการลูกสิ้นสุด สัญญาณเป็นรูปแบบ IPC ที่ใช้ทรัพยากรน้อย
สัญญาณทั่วไป
สัญญาณบางรายการที่คุณจะพบเป็นประจำ:
SIGINTการขัดจังหวะ (Ctrl-C)SIGTERMคำขอให้ยุติการทำงานอย่างสุภาพSIGKILLการบังคับยุติ (ไม่สามารถดักจับได้)SIGCHLDกระบวนการลูกเปลี่ยนสถานะSIGSEGVการเข้าถึงหน่วยความจำที่ไม่ถูกต้อง
การจัดการเริ่มต้น
สัญญาณแต่ละตัวมีการดำเนินการเริ่มต้น ได้แก่ ยุติการทำงาน, ยุติการทำงานพร้อมสร้าง core dump, เพิกเฉย, หยุด หรือ ทำงานต่อ คุณสามารถแทนที่การดำเนินการส่วนใหญ่ได้ด้วย handler
การติดตั้ง Handler
วิธีสมัยใหม่ที่ใช้ได้กับหลายแพลตฟอร์มในการกำหนด handler คือ sigaction โดย handler เป็นฟังก์ชันที่รับหมายเลขสัญญาณ
#include <signal.h>
#include <stdio.h>
void on_signal(int sig) {
/* note: printf is not async-signal-safe; for demo only */
write(1, "caught\n", 7);
}
int install(void) {
struct sigaction sa = {0};
sa.sa_handler = on_signal;
return sigaction(SIGINT, &sa, NULL);
}เหตุใดจึงไม่ใช้ signal()
ฟังก์ชันเก่าอย่าง signal() มีพฤติกรรมไม่สอดคล้องกันในแต่ละระบบ (handler ถูกตั้งค่าใหม่ และไม่มีตัวควบคุม SA_RESTART) ขอแนะนำให้ใช้ sigaction ซึ่งมีข้อกำหนดชัดเจนและใช้ได้กับหลายแพลตฟอร์ม
ฟังก์ชันที่ปลอดภัยต่อสัญญาณแบบอะซิงโครนัส
handler อาจขัดจังหวะโค้ดของคุณได้ทุกจุด ดังนั้นจึงเรียกใช้ได้เฉพาะฟังก์ชันที่ ปลอดภัยต่อสัญญาณแบบอะซิงโครนัส เช่น write การเรียก printf หรือ malloc จาก handler อาจทำให้เกิดการหยุดรอแบบ deadlock หรือข้อมูลเสียหาย
การใช้แฟล็ก volatile
รูปแบบที่ปลอดภัยคือ ให้ handler ตั้งค่าแฟล็ก volatile sig_atomic_t แล้วให้ลูปหลักตรวจสอบแฟล็กนั้น วิธีนี้ทำให้ handler มีขนาดเล็กและปลอดภัย
#include <signal.h>
volatile sig_atomic_t stop = 0;
void handler(int sig) {
stop = 1; /* only set a flag */
}
/* main loop: while (!stop) { do_work(); } */การส่งสัญญาณ
ใช้ kill(pid, sig) เพื่อส่งสัญญาณไปยังกระบวนการอื่น หรือใช้ raise(sig) เพื่อส่งสัญญาณให้ตัวเอง แม้ชื่อจะเป็น kill แต่ฟังก์ชันนี้ส่งสัญญาณได้ทุกชนิด ไม่ใช่เฉพาะสัญญาณที่ทำให้ถึงแก่การทำงานเท่านั้น
#include <signal.h>
int notify(int pid) {
return kill(pid, SIGTERM); /* ask process to terminate */
}การบล็อกสัญญาณ
เพื่อปกป้องส่วนสำคัญของโค้ด ให้ บล็อก สัญญาณชั่วคราวด้วย sigprocmask และชุดสัญญาณ สัญญาณที่ถูกบล็อกจะค้างอยู่ในสถานะ รอดำเนินการ และจะถูกส่งให้ทันทีเมื่อยกเลิกการบล็อก
#include <signal.h>
void block_int(void) {
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigprocmask(SIG_BLOCK, &set, NULL);
}การเก็บกวาดกระบวนการลูกด้วย SIGCHLD
เมื่อกระบวนการลูกสิ้นสุดลง เคอร์เนลจะส่ง SIGCHLD handler ที่เรียก waitpid จะเก็บกวาดกระบวนการลูก ป้องกันไม่ให้เกิดกระบวนการ ซอมบี้ ที่ค้างอยู่ในตารางกระบวนการ
#include <signal.h>
#include <sys/wait.h>
void reap(int sig) {
while (waitpid(-1, NULL, WNOHANG) > 0)
; /* reap all finished children */
}สัญญาณที่ดักจับไม่ได้
มีสัญญาณสองตัวที่ไม่อาจเปลี่ยนแปลงได้: SIGKILL จะยุติการทำงานเสมอ และ SIGSTOP จะหยุดกระบวนการเสมอ สัญญาณเหล่านี้ไม่สามารถดักจับ บล็อก หรือเพิกเฉยได้ จึงทำให้ระบบมีวิธีควบคุมกระบวนการที่รับประกันได้
ตรวจสอบความเข้าใจ
ทดสอบความเข้าใจเกี่ยวกับสัญญาณของคุณ
สรุปทบทวน
คุณได้เรียนรู้เกี่ยวกับสัญญาณสำหรับการแจ้งเตือนแบบอะซิงโครนัส
- ติดตั้ง handler ด้วย
sigactionแทนsignalแบบเก่า - handler ต้องใช้ฟังก์ชันที่ปลอดภัยต่อสัญญาณแบบอะซิงโครนัส ขอแนะนำให้ตั้งค่าแฟล็ก
- ส่งสัญญาณด้วย
kill/raiseและบล็อกด้วยsigprocmask - เก็บกวาดกระบวนการลูกเมื่อได้รับ SIGCHLD ส่วน SIGKILL และ SIGSTOP ไม่สามารถดักจับได้
เรียนรู้ C ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 39
- บทเรียน
- 144
คำถามที่พบบ่อย
บทเรียน “สัญญาณ” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “สัญญาณ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “สัญญาณ”
การแจ้งเตือนแบบอะซิงโครนัส คุณปฏิบัติ C Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “สัญญาณ” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C Academy นี้ได้ไหม
ได้ บทเรียน C Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ