กลับไปหน้าบทความ

อ่าน 4 นาที

การจัดการสัญญาณ C

ใน ไลบรารีมาตรฐาน ของภาษาซีการประมวลผลสัญญาณจะกำหนดวิธีการที่โปรแกรมจัดการกับสัญญาณ ต่างๆ ขณะที่กำลังทำงาน สัญญาณอาจรายงานพฤติกรรมที่ผิดปกติภายในโปรแกรม (เช่นการหารด้วยศูนย์ )

การจัดการสัญญาณ C

ใน ไลบรารีมาตรฐาน ของภาษาซีการประมวลผลสัญญาณจะกำหนดวิธีการที่โปรแกรมจัดการกับสัญญาณ ต่างๆ ขณะที่กำลังทำงาน สัญญาณอาจรายงานพฤติกรรมที่ผิดปกติภายในโปรแกรม (เช่นการหารด้วยศูนย์ ) หรือสัญญาณอาจรายงานเหตุการณ์แบบอะซิงโครนัสภายนอกโปรแกรม (เช่น การที่ใครบางคนกดปุ่มความสนใจแบบโต้ตอบบนแป้นพิมพ์)

สัญญาณมาตรฐาน

มาตรฐาน C กำหนดสัญญาณเพียง 6 สัญญาณเท่านั้น โดยทั้งหมดถูกกำหนดไว้ในส่วนหัว<signal.h>( <csignal>): [ 1 ]

  • SIGABRT– "การทำแท้ง", การยุติการคลอดที่ผิดปกติ
  • SIGFPE– ข้อผิดพลาด เกี่ยวกับเลขทศนิยม
  • SIGILL– คำสั่งที่ "ผิดกฎหมาย" หรือไม่ถูกต้อง
  • SIGINT– "การขัดจังหวะ" คือคำขอความสนใจแบบโต้ตอบที่ส่งไปยังโปรแกรม
  • SIGSEGV– " การละเมิดการแบ่งส่วนหน่วยความจำ " การเข้าถึงหน่วยความจำที่ไม่ถูกต้อง
  • SIGTERM– "ยุติ", ส่งคำขอการยุติไปยังโปรแกรม

อาจมีการระบุสัญญาณเพิ่มเติมใน<signal.h>ส่วนหัวโดยการใช้งาน ตัวอย่างเช่น ระบบปฏิบัติการ Unix และ ระบบปฏิบัติการ ที่คล้าย Unix (เช่นLinux ) กำหนดสัญญาณเพิ่มเติมมากกว่า 15 รายการ ดูUnix signal [ 2 ]

การดีบัก

  • SIGTRAPเพื่อวัตถุประสงค์ในการแก้ไขข้อผิดพลาด โปรแกรมนี้ขึ้นอยู่กับแพลตฟอร์ม และสามารถใช้งานได้บนระบบปฏิบัติการที่คล้ายUnix

การจัดการ

สามารถสร้างสัญญาณได้โดยการเรียกใช้ฟังก์ชันraise()หรือkill()การเรียกใช้ระบบ เช่นraise()ส่งสัญญาณไปยังกระบวนการปัจจุบัน หรือkill()ส่งสัญญาณไปยังกระบวนการที่ระบุ

ตัวจัดการสัญญาณคือฟังก์ชันที่ถูกเรียกโดยสภาพแวดล้อมเป้าหมายเมื่อเกิดสัญญาณที่เกี่ยวข้อง สภาพแวดล้อมเป้าหมายจะระงับการทำงานของโปรแกรมจนกว่าตัวจัดการสัญญาณจะส่งค่ากลับหรือเรียกใช้ฟังก์ชันlongjmp()อื่น

ตัวจัดการสัญญาณสามารถตั้งค่าได้ด้วยsignal()หรือsigaction()พฤติกรรมของ ได้signal()ถูกเปลี่ยนแปลงหลายครั้งตลอดประวัติศาสตร์ และไม่แนะนำให้ใช้[ 3 ]สามารถใช้งานได้เฉพาะเมื่อใช้เพื่อตั้งค่าการจัดการสัญญาณเป็น SIG_DFL หรือ SIG_IGN เท่านั้น ตัวจัดการสัญญาณสามารถระบุได้สำหรับสัญญาณทั้งหมด ยกเว้นสองสัญญาณ ( ไม่สามารถดักจับ บล็อก หรือเพิกเฉยต่อ SIGKILLและSIGSTOPได้)

หากสัญญาณรายงานข้อผิดพลาดภายในโปรแกรม (และสัญญาณนั้นไม่ใช่แบบอะซิงโครนัส) ตัวจัดการสัญญาณสามารถยุติการทำงานได้โดยการเรียกใช้เมธอดabort(), exit(), longjmp()หรือ

ฟังก์ชัน

การทำงาน คำอธิบาย
raiseส่งสัญญาณไปยังกระบวนการเรียกอย่างไม่เป็นธรรมชาติ
killส่งสัญญาณไปยังกระบวนการที่กำหนดไว้โดยเทียม
signalกำหนดการกระทำที่จะเกิดขึ้นเมื่อโปรแกรมได้รับสัญญาณเฉพาะ

ตัวอย่างการใช้งาน

#include <signal.h> #include <stdio.h> #include <stdlib.h>สถานะsig_atomic_t ที่ผันผวน= 0 ;static void catch_function ( int signo ) { status = signo ; }int main ( void ) { // ตั้งค่าฟังก์ชันด้านบนเป็นตัวจัดการสัญญาณสำหรับสัญญาณ SIGINT: if ( signal ( SIGINT , catch_function ) == SIG_ERR ) { fprintf ( stderr , "เกิดข้อผิดพลาดขณะตั้งค่าตัวจัดการสัญญาณ\n " ); return EXIT_FAILURE ; } printf ( "กำลังยกสัญญาณความสนใจแบบโต้ตอบ" ); if ( raise ( SIGINT )) { fprintf ( stderr , "เกิดข้อผิดพลาดในการยกสัญญาณ\n " ); return EXIT_FAILURE ; } if ( status == SIGINT ) { printf ( "จับสัญญาณความสนใจแบบโต้ตอบได้แล้ว" ); } printf ( "กำลังออกจากโปรแกรม" ); return EXIT_SUCCESS ; // ออกจากโปรแกรมหลังจากยกสัญญาณ}

ภาษาอื่นๆ

ซี++

โดยทั่วไปแล้ว สัญญาณในภาษา C จะถูกใช้งานใน C++ ในลักษณะเดียวกับในภาษา C อย่างไรก็ตาม เรายังสามารถเขียนฟังก์ชันห่อหุ้มสำหรับการใช้งาน ในรูปแบบ RAII ได้อีกด้วย

ส่งออกโมดูลวิกิพีเดียตัวอย่าง;import < csignal > ; // จำเป็นสำหรับการได้มาซึ่งมาโครimport std ;โดยใช้std :: function ;ส่งออกเนมสเปซวิกิพีเดีย:: examples {คลาสSignal { private : using Handler = function < void ( int ) > ; int sig ; public : static constexpr int ABRT = SIGABRT ; static constexpr int FPE = SIGFPE ; static constexpr int ILL = SIGILL ; static constexpr int INT = SIGINT ; static constexpr int SEGV = SIGSEGV ; static constexpr int TERM = SIGTERM ; static constexpr int DFL = SIGDFL ; static constexpr int IGN = SIGIGN ; static constexpr int ERR = SIGERR ;สัญญาณที่ชัดเจน( int sig ) : sig { sig } {}[[ nodiscard ]] int getSignal () const noexcept { return sig ; }ตัวจัดการตัวจัดการ( ตัวจัดการตัวจัดการ) const noยกเว้น{ return std :: สัญญาณ( sig ตัวจัดการ) ; }int raise () const noexcept { return std :: raise ( sig ); } };}

นอกจากนี้ยังสามารถทำได้ด้วยBoostboost::asio::signal_set โดย ใช้ คลาส

ซี#

สัญญาณ C สามารถใช้ร่วมกับP/InvokeและMono.Unix.Native.Syscall.

ชวา

สัญญาณ C สามารถใช้งานได้อย่างไม่เป็นทางการในภาษาJava จาก โมดูลjdk.unsupportedโดยใช้คลาส JVM ภายในsun.misc.Signalและอินเทอร์เฟsun.misc.SignalHandler[ 4 ]

แพ็คเกจorg.wikipedia.example ;import sun.misc.Signal ; import sun.misc.SignalHandler ;public class Example { public static void main ( String [] args ) { SignalHandler handler = new SignalHandler () { public void handle ( Signal sig ) { boolean handled = handlers . get ( type ). handle ( type ); if ( ! handled ) { if ( type . getDefaultAction () == SignalType . DefaultAction . IGNORE ) { SignalHandler . SIG_IGN . handle ( sig ); } else { SignalHandler . SIG_DFL . handle ( sig ); } } } }; Signal . handle ( new Signal ( "INT" ), handler ); } }

สนิม

สามารถใช้สัญญาณร่วมกับ crate signal_hookใน Rust ได้[ 5 ]

ใช้std :: process ; ใช้std :: thread ; ใช้std :: time :: Duration ;ใช้signal_hook :: consts :: signal :: * ; ใช้signal_hook :: iterator :: Signals ;fn main () { let mut signals : Signals = Signals :: new ( & [ SIGINT , SIGTERM ]). expect ( "Failed to set up signal handling" );thread :: spawn ( move || { for signal in signals.forever ( ) { match signal { SIGINT => { println! ( "ได้รับ SIGINT (Ctrl+C) ออกจากโปรแกรมอย่างราบรื่น" ) ; process :: exit ( 0 ); } SIGTERM => { println! ( "ได้รับ SIGTERM ออกจากโปรแกรมอย่างราบรื่น" ); process :: exit ( 0 ); } _ => unreachable! (), } } });loop { println! ( "กำลังทำงาน..." ); thread :: sleep ( Duration :: from_secs ( 2 )); } }

ดูเพิ่มเติม

ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=C_signal_handling&oldid=1340044347 "

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ การจัดการสัญญาณ C

ใน ไลบรารีมาตรฐาน ของภาษาซีการประมวลผลสัญญาณจะกำหนดวิธีการที่โปรแกรมจัดการกับสัญญาณ ต่างๆ ขณะที่กำลังทำงาน สัญญาณอาจรายงานพฤติกรรมที่ผิดปกติภายในโปรแกรม (เช่นการหารด้วยศูนย์ )

สัญญาณมาตรฐาน

มาตรฐาน C กำหนดสัญญาณเพียง 6 สัญญาณเท่านั้น โดยทั้งหมดถูกกำหนดไว้ในส่วนหัว ( ): [ 1 ]

การดีบัก

SIGTRAP เพื่อวัตถุประสงค์ในการแก้ไขข้อผิดพลาด โปรแกรมนี้ขึ้นอยู่กับแพลตฟอร์ม และสามารถใช้งานได้บนระบบปฏิบัติการที่คล้าย Unix

การจัดการ

สามารถสร้างสัญญาณได้โดยการเรียกใช้ฟังก์ชัน raise() หรือ kill() การเรียกใช้ระบบ เช่น raise() ส่งสัญญาณไปยังกระบวนการปัจจุบัน หรือ kill() ส่งสัญญาณไปยังกระบวนการที่ระบุ