SIGINT अन्य समाप्ति संकेतों जैसे SIGTERM, SIGQUIT और SIGKILL से कैसे संबंधित है?


103

POSIX सिस्टम पर, समाप्ति संकेतों में आमतौर पर निम्न क्रम होता है (कई MAN पृष्ठों और POSIX कल्पना के अनुसार):

  1. SIGTERM - विनम्रता से एक प्रक्रिया को समाप्त करने के लिए कहें। यह अस्थायी रूप से फ़ाइलों को हटाने और सभी संसाधनों (फ़ाइलों, सॉकेट्स, चाइल्ड प्रॉसेस, आदि) की सफाई करते हुए, शान से समाप्त हो जाएगा।

  2. हस्ताक्षर - अधिक बलपूर्वक अनुरोध। यह अपमानजनक, अभी भी संसाधनों की सफाई को पूरी तरह से समाप्त करने की आवश्यकता है, लेकिन शायद अस्थायी फ़ाइलों को नष्ट न करें, शायद डिबग जानकारी कहीं लिखें; कुछ सिस्टम पर एक कोर डंप भी लिखा जाएगा (भले ही संकेत ऐप द्वारा पकड़ा जाए या नहीं)।

  3. SIGKILL - सबसे जोरदार अनुरोध। प्रक्रिया को कुछ भी करने के लिए नहीं कहा जाता है, लेकिन सिस्टम प्रक्रिया को साफ करेगा, चाहे वह ऐसा हो या न हो। सबसे अधिक संभावना एक कोर डंप लिखा है।

SIGINT उस तस्वीर में कैसे फिट होता है? एक CLI प्रक्रिया आमतौर पर SIGINT द्वारा समाप्त की जाती है जब उपयोगकर्ता CRTL + C से टकराता है, हालांकि एक पृष्ठभूमि प्रक्रिया को SIGINT द्वारा KIL उपयोगिता का उपयोग करके भी समाप्त किया जा सकता है। अगर मैं SIGINT SIGTERM से अधिक या कम बलशाली हो या SIGINT और SIGTERM के बीच कोई अंतर हो तो क्या मैं चश्मे या हेडर फ़ाइलों में नहीं देख सकता।

अपडेट करें:

टर्मिनेशन सिग्नल का सबसे अच्छा विवरण जो मुझे अब तक मिला है वह GNU LibC प्रलेखन में है । यह बहुत अच्छी तरह से समझाता है कि SIGTERM और SIGQUIT के बीच एक अंतर है।

यह SIGTERM के बारे में कहता है:

किसी कार्यक्रम को विनम्रतापूर्वक समाप्त करने का सामान्य तरीका है।

और यह SIGQUIT के बारे में कहता है:

[...] और एक कोर डंप का उत्पादन करता है जब यह प्रक्रिया को समाप्त करता है, बस प्रोग्राम त्रुटि संकेत की तरह। आप इसे उपयोगकर्ता द्वारा प्रोग्राम एरर कंडीशन "डिटेक्ट" के रूप में सोच सकते हैं। [...] SIGQUIT को संभालने में कुछ प्रकार के क्लीनअप्स को छोड़ दिया जाता है। उदाहरण के लिए, यदि प्रोग्राम अस्थायी फ़ाइलें बनाता है, तो उसे अस्थायी फ़ाइलों को हटाकर अन्य समाप्ति अनुरोधों को संभालना चाहिए। लेकिन SIGQUIT के लिए बेहतर है कि उन्हें डिलीट न किया जाए, ताकि उपयोगकर्ता कोर डंप के साथ मिलकर उनकी जांच कर सकें।

और SIGHUP को भी पर्याप्त रूप से समझाया गया है। SIGHUP वास्तव में एक समाप्ति संकेत नहीं है, इसका मतलब है कि उपयोगकर्ता के लिए "कनेक्शन" खो गया है, इसलिए एप्लिकेशन उपयोगकर्ता से किसी भी आगे के आउटपुट (जैसे stdout / stderr आउटपुट) को पढ़ने की उम्मीद नहीं कर सकता है और उम्मीद से कोई इनपुट नहीं है अब किसी भी उपयोगकर्ता। अधिकांश ऐप के लिए जिसका अर्थ है कि वे बेहतर तरीके से छोड़ देते हैं। सिद्धांत रूप में एक ऐप यह भी तय कर सकता है कि यह राइट मोड में जाता है जब एक SIGHUP प्राप्त होता है और अब एक पृष्ठभूमि प्रक्रिया के रूप में चलता है, एक कॉन्फ़िगर लॉग फ़ाइल में आउटपुट लिखता है। पहले से ही पृष्ठभूमि में चल रहे अधिकांश डेमों के लिए, S आमतौर पर इसका अर्थ है कि वे अपनी कॉन्फ़िगरेशन फ़ाइलों को फिर से जांचेंगे, इसलिए आप इसे कॉन्फ़िगर फ़ाइलों को संपादित करने के बाद पृष्ठभूमि प्रक्रियाओं में भेजते हैं।

हालाँकि इस पृष्ठ पर SIGINT की कोई उपयोगी व्याख्या नहीं है, इसके अलावा यह CRTL + C द्वारा भेजा गया है। क्या कोई कारण है कि कोई SIGTERM से अलग तरीके से SIGINT को हैंडल करेगा? यदि हां, तो इसका क्या कारण होगा और हैंडलिंग अलग कैसे होगी?


1
अच्छा प्रश्न। मुझे संदेह है कि उत्तर में कुछ ऐतिहासिक यूनिक्स अपराध शामिल होंगे।
एलेक्स बी

मुझे पता है कि यह सवाल पुराना है, लेकिन अगर कोई भी आपके (लिनक्स) ओएस के लिए संकेतों की एक व्यापक सूची के लिए यहां आया है, तो उन्हें sudo fuser -lआपके कमांड प्रॉम्प्ट पर टाइप करके पाया जा सकता है । मेरे लिए यह लाता है:HUP INT QUIT ILL TRAP ABRT IOT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH IO PWR SYS UNUSED
निक बुल

3
kill -lसंकेतों की सूची के लिए भी प्रयास करें ।
AAAfarmclub

जवाबों:


88

SIGTERM और SIGKILL का उद्देश्य सामान्य उद्देश्य "इस प्रक्रिया को समाप्त करना" है। SIGTERM (डिफ़ॉल्ट रूप से) और SIGKILL (हमेशा) प्रक्रिया समाप्ति का कारण होगा। SIGTERM को प्रक्रिया द्वारा पकड़ा जा सकता है (जैसे कि अगर वह चाहे तो अपनी स्वयं की सफाई कर सकता है), या यहां तक ​​कि पूरी तरह से अनदेखा कर सकता है; लेकिन SIGKILL को पकड़ा या अनदेखा नहीं किया जा सकता है।

SIGINT और SIGQUIT को विशेष रूप से टर्मिनल के अनुरोधों के लिए अभिप्रेत है: इन संकेतों को उत्पन्न करने के लिए विशेष टर्मिनल वर्ण निर्दिष्ट किए जा सकते हैं (टर्मिनल नियंत्रण सेटिंग्स के आधार पर)। SIGINT के लिए डिफ़ॉल्ट कार्रवाई SIGTERM के लिए डिफ़ॉल्ट कार्रवाई और SIGKILL के लिए अपरिवर्तनीय कार्रवाई के समान प्रक्रिया समाप्ति है; SIGQUIT के लिए डिफ़ॉल्ट कार्रवाई भी प्रक्रिया समाप्ति है, लेकिन अतिरिक्त कार्यान्वयन-परिभाषित क्रियाएं हो सकती हैं, जैसे कि कोर डंप की पीढ़ी। यदि आवश्यक हो तो प्रक्रिया द्वारा या तो पकड़ा जा सकता है या अनदेखा किया जा सकता है।

जैसा कि आप कहते हैं, SIGHUP, यह इंगित करने के लिए लक्षित है कि टर्मिनल कनेक्शन खो गया है, बल्कि इस तरह के समाप्ति संकेत के रूप में। लेकिन, फिर से, SIGHUP के लिए डिफ़ॉल्ट क्रिया (यदि प्रक्रिया इसे नहीं पकड़ती है या इसे अनदेखा नहीं करती है) प्रक्रिया को उसी तरह समाप्त करना है जैसे कि SIGTERM आदि।

POSIX परिभाषाओं में एक तालिका है signal.hजिसके लिए विभिन्न संकेतों और उनके डिफ़ॉल्ट कार्यों और उद्देश्यों को सूचीबद्ध करता है, और सामान्य टर्मिनल इंटरफ़ेस अध्याय में टर्मिनल से संबंधित संकेतों पर बहुत अधिक विवरण शामिल हैं।


10
यह प्रमुख बिंदु है: एकल और वर्णों को टर्मिनल से एकल वर्णों का उपयोग करके उत्पन्न किया जा सकता है, जबकि कार्यक्रम चल रहा है। अन्य संकेतों को किसी अन्य कार्यक्रम द्वारा उत्पन्न किया जाना है, किसी भी तरह (उदाहरण के लिए मार कमांड)। SIGQUIT की तुलना में SIGINT कम हिंसक है; उत्तरार्द्ध एक कोर डंप का उत्पादन करता है। SIGKILL फंस नहीं सकता। यदि आपका कनेक्शन हैंग हो जाता है (विंडो बंद हो जाती है, आदि) तो SIGHUP उत्पन्न होता है। इसलिए, इन सभी के अलग-अलग अर्थ हैं।
जोनाथन लेफलर

TTY डीमिस्टिफ़ाइड में कुछ आसानी से पचने योग्य जानकारी होती है कि कैसे कर्नेल के ट्टी सबसिस्टम के साथ सिग्नल इंटरैक्ट करते हैं। आपके उत्तर के लिए कुछ संदर्भ जोड़ता है।
डैनियल नेल्सन

2
ऐसा लगता है कि ऐनक बहुत सटीक नहीं है, लेकिन मेरी समझ यह है कि SIgint प्रोग्राम को वर्तमान कार्रवाई को रोकने के लिए कहता है, जरूरी नहीं कि इसे छोड़ दिया जाए। एक प्रोग्राम के लिए केवल प्रति रन एक क्रिया है जो क्विटिंग का अर्थ है, लेकिन एक इंटरएक्टिव प्रोग्राम के लिए, जिसमें कुछ प्रकार के रीड-इवल-प्रिंट लूप होते हैं, इसका मतलब यह हो सकता है कि वर्तमान इवैल पर छोड़ दें और उपयोगकर्ता इनपुट पढ़ने पर वापस जाएं। मुझे लगता है कि यह कम ही है।
bdsl

रिबूट के दौरान क्या संकेत भेजा जाता है?
दानिशस्कूल

10

जैसा कि डार्कडस्ट ने उल्लेख किया है कि कई संकेतों के परिणाम समान हैं, लेकिन प्रक्रियाएं उन्हें अलग-अलग कार्यों को संलग्न करके यह बता सकती हैं कि प्रत्येक सिग्नल कैसे उत्पन्न होता है। FreeBSD कर्नेल स्रोत कोड (kern_sig.c) को देखते हुए, मैं देखता हूं कि दो सिग्नल एक ही तरह से संभाले जाते हैं, वे प्रक्रिया को समाप्त करते हैं और किसी भी थ्रेड पर वितरित होते हैं।

SA_KILL|SA_PROC,             /* SIGINT */
SA_KILL|SA_PROC,             /* SIGTERM */

9

man 7 signal

यह लिनक्स मैन-पेज प्रोजेक्ट का सुविधाजनक गैर-मानक मैनपेज है जिसे आप अक्सर लिनक्स सिग्नल की जानकारी के लिए देखना चाहते हैं।

संस्करण 3.22 में दिलचस्प बातों का उल्लेख है:

संकेत SIGKILL और SIGSTOP को पकड़ा, अवरुद्ध या अनदेखा नहीं किया जा सकता है।

और तालिका में शामिल हैं:

Signal     Value     Action   Comment
----------------------------------------------------------------------
SIGHUP        1       Term    Hangup detected on controlling terminal
                              or death of controlling process
SIGINT        2       Term    Interrupt from keyboard
SIGQUIT       3       Core    Quit from keyboard
SIGILL        4       Core    Illegal Instruction
SIGABRT       6       Core    Abort signal from abort(3)
SIGFPE        8       Core    Floating point exception
SIGKILL       9       Term    Kill signal
SIGSEGV      11       Core    Invalid memory reference
SIGPIPE      13       Term    Broken pipe: write to pipe with no
                              readers
SIGALRM      14       Term    Timer signal from alarm(2)
SIGTERM      15       Term    Termination signal
SIGUSR1   30,10,16    Term    User-defined signal 1
SIGUSR2   31,12,17    Term    User-defined signal 2
SIGCHLD   20,17,18    Ign     Child stopped or terminated
SIGCONT   19,18,25    Cont    Continue if stopped
SIGSTOP   17,19,23    Stop    Stop process
SIGTSTP   18,20,24    Stop    Stop typed at tty
SIGTTIN   21,21,26    Stop    tty input for background process
SIGTTOU   22,22,27    Stop    tty output for background process

जो संकेत को सारांशित करता Actionहै जो कि उदाहरण को SIGQUIT से अलग करता है, क्योंकि SIGQUIT में कार्रवाई Coreऔर SIGINT है Term

क्रियाएँ एक ही दस्तावेज़ में दर्ज हैं:

The entries in the "Action" column of the tables below specify the default disposition for each signal, as follows:

Term   Default action is to terminate the process.

Ign    Default action is to ignore the signal.
Core   Default action is to terminate the process and dump core (see core(5)).
Stop   Default action is to stop the process.
Cont   Default action is to continue the process if it is currently stopped.

मैं कर्नेल के दृष्टिकोण से SIGTERM और SIGINT के बीच कोई अंतर नहीं देख सकता क्योंकि दोनों में कार्रवाई है Termऔर दोनों को पकड़ा जा सकता है। ऐसा लगता है कि सिर्फ एक "आम उपयोग सम्मेलन भेद" है:

  • जब आप CTRL-C टर्मिनल से करते हैं तो SIGINT होता है
  • SIGTERM द्वारा भेजा गया डिफ़ॉल्ट संकेत है kill

कुछ संकेत एएनएसआई सी और अन्य नहीं हैं

एक काफी अंतर यह है कि:

  • SIGINT और SIGTERM ANSI C हैं, इस प्रकार अधिक पोर्टेबल हैं
  • SIGQUIT और SIGKILL नहीं हैं

इन्हें C99 ड्राफ्ट N1256 के "7.14 सिग्नल हैंडलिंग" खंड पर वर्णित किया गया है :

  • एक संवादात्मक ध्यान संकेत की SIGINT रसीद
  • SIGTERM कार्यक्रम में भेजा गया एक समाप्ति अनुरोध

जो SIGINT को एक इंटरैक्टिव Ctrl + C के लिए एक अच्छा उम्मीदवार बनाता है।

POSIX 7

POSIX 7 signal.hहेडर के साथ संकेतों को दस्तावेजित करता है : https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html

इस पृष्ठ में भी निम्नलिखित रुचिकर तालिका है, जिसमें हमारे द्वारा देखी गई कुछ चीजों का उल्लेख है man 7 signal:

Signal    Default Action   Description
SIGABRT   A                Process abort signal.
SIGALRM   T                Alarm clock.
SIGBUS    A                Access to an undefined portion of a memory object.
SIGCHLD   I                Child process terminated, stopped,
SIGCONT   C                Continue executing, if stopped.
SIGFPE    A                Erroneous arithmetic operation.
SIGHUP    T                Hangup.
SIGILL    A                Illegal instruction.
SIGINT    T                Terminal interrupt signal.
SIGKILL   T                Kill (cannot be caught or ignored).
SIGPIPE   T                Write on a pipe with no one to read it.
SIGQUIT   A                Terminal quit signal.
SIGSEGV   A                Invalid memory reference.
SIGSTOP   S                Stop executing (cannot be caught or ignored).
SIGTERM   T                Termination signal.
SIGTSTP   S                Terminal stop signal.
SIGTTIN   S                Background process attempting read.
SIGTTOU   S                Background process attempting write.
SIGUSR1   T                User-defined signal 1.
SIGUSR2   T                User-defined signal 2.
SIGTRAP   A                Trace/breakpoint trap.
SIGURG    I                High bandwidth data is available at a socket.
SIGXCPU   A                CPU time limit exceeded.
SIGXFSZ   A                File size limit exceeded.

व्यस्त बॉक्स init

बिजीबॉक्स की 1.29.2 डिफॉल्ट rebootकमांड एक SIGTERM को प्रोसेस में भेजती है, एक सेकंड के लिए सोती है, और फिर SIGKILL को भेजती है। यह विभिन्न विकृतियों के बीच एक आम सम्मेलन प्रतीत होता है।

जब आप एक व्यस्त बॉक्स सिस्टम को बंद करते हैं:

reboot

यह init प्रक्रिया के लिए एक संकेत भेजता है।

फिर, इनिट सिग्नल हैंडलर कॉलिंग समाप्त करता है:

static void run_shutdown_and_kill_processes(void)
{
    /* Run everything to be run at "shutdown".  This is done _prior_
     * to killing everything, in case people wish to use scripts to
     * shut things down gracefully... */
    run_actions(SHUTDOWN);

    message(L_CONSOLE | L_LOG, "The system is going down NOW!");

    /* Send signals to every process _except_ pid 1 */
    kill(-1, SIGTERM);
    message(L_CONSOLE, "Sent SIG%s to all processes", "TERM");
    sync();
    sleep(1);

    kill(-1, SIGKILL);
    message(L_CONSOLE, "Sent SIG%s to all processes", "KILL");
    sync();
    /*sleep(1); - callers take care about making a pause */
}

जो टर्मिनल को प्रिंट करता है:

The system is going down NOW!
Sent SIGTERM to all processes
Sent SIGKILL to all processes

यहाँ इसका एक न्यूनतम ठोस उदाहरण है

कर्नेल द्वारा भेजे गए संकेत


8

सिगिंट बनाम सिगटरम के लिए एक त्वरित Google खोज के बाद , यह दोनों के बीच एकमात्र इच्छित अंतर की तरह दिखता है, चाहे वह कीबोर्ड शॉर्टकट द्वारा या स्पष्ट कॉल द्वारा शुरू किया गया हो kill

नतीजतन, आप, उदाहरण के लिए, sigint को रोक सकते हैं और इसके साथ कुछ विशेष कर सकते हैं, यह जानते हुए कि यह संभवतः कीबोर्ड शॉर्टकट द्वारा भेजा गया था। शायद स्क्रीन को ताज़ा करें या कुछ और, मरने के बजाय (अनुशंसित नहीं है, क्योंकि लोग ^Cकार्यक्रम को मारने की उम्मीद करते हैं, सिर्फ एक उदाहरण)।

मैंने यह भी सीखा है कि ^\सिगक्विट भेजना चाहिए, जिसे मैं स्वयं उपयोग करना शुरू कर सकता हूं। बहुत उपयोगी लगता है।


3

killसिस्टम का उपयोग करना (सिस्टम कॉल और यूटिलिटी दोनों) आप किसी भी प्रक्रिया को लगभग कोई भी संकेत भेज सकते हैं, यह देखते हुए कि आपको अनुमति मिल गई है। एक प्रक्रिया यह नहीं बता सकती है कि सिग्नल जीवन में कैसे आया और किसने भेजा है।

यह कहा जा रहा है, SIGINT वास्तव में Ctrl-C रुकावट को गाने के लिए है, जबकि SIGTERM सामान्य टर्मिनल संकेत है। सिग्नल के "अधिक शक्तिशाली" होने की कोई अवधारणा नहीं है, एकमात्र अपवाद है कि ऐसे सिग्नल हैं जो अवरुद्ध या संभाले नहीं जा सकते हैं (मैन पेज के अनुसार SIGKILL और SIGSTOP)।

एक सिग्नल केवल एक सिग्नल से केवल "अधिक शक्तिशाली" हो सकता है कि कैसे प्राप्त करने की प्रक्रिया सिग्नल को संभालती है (और उस सिग्नल के लिए डिफ़ॉल्ट कार्रवाई क्या है)। उदाहरण के लिए, डिफ़ॉल्ट रूप से, SIGTERM और SIGINT दोनों समाप्ति की ओर ले जाते हैं। लेकिन अगर आप SIGTERM को नजरअंदाज करते हैं तो यह आपकी प्रक्रिया को समाप्त नहीं करेगा, जबकि SIGINT अभी भी करता है।


0

कुछ संकेतों के अपवाद के साथ, सिग्नल हैंडलर विभिन्न सिग्नलों को पकड़ सकता है, या सिग्नल प्राप्त होने पर डिफ़ॉल्ट व्यवहार को संशोधित किया जा सकता है। देखें signal(7)विवरण के लिए आदमी पेज।


हां, लेकिन अगर मुझे किसी गायक के "अर्थ" का पता नहीं है, तो सिग्नल को पकड़ना व्यर्थ है, क्योंकि मुझे नहीं पता होगा कि मुझे अपने आवेदन में क्या करना है। GNU C उदाहरण SIGQUIT और SIGTERM के बीच अंतर बताता है। लेकिन यह SIGINT: gnu.org/s/libc/manual/html_node/Termination-Signals.html
Mecki

" SIGINT(" प्रोग्राम इंटरप्ट ") सिग्नल तब भेजा जाता है जब उपयोगकर्ता INTR वर्ण (सामान्य रूप से C-c) टाइप करता है ।" "कीबोर्ड से SIGINT 2 टर्म इंटरप्ट" आपने Ctrl-C को हिट किया, SIGINTभेजा गया। प्रक्रिया सामान्य रूप से मर जाती है। और क्या देना है?
इग्नासियो वाज़केज़-अब्राम्स

संभावित रूप से इस आशय का विवरण हो सकता है कि प्रोग्रामर को यह मान लेना चाहिए कि उपयोगकर्ता के पास जब संदेश का ctrl-c, Iethe शब्दार्थ होगा। एक उदाहरण के रूप में HTTP कल्पना स्पष्ट करती है कि जब कोई उपयोगकर्ता GET अनुरोध भेजता है, तो सर्वर को यह नहीं मानना ​​चाहिए कि वे चाहते हैं कि वह कुछ भी कर सकता है सिवाय प्रतिक्रिया वापस भेजे।
bdsl
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.