2008-10-08 25 views
5

में ctrl-break सिग्नल को कैसे प्रबंधित करें, शुरू करने से पहले, मैं यह स्पष्ट करना चाहता हूं कि यह एक कमांड लाइन उपकरण नहीं है, लेकिन एक ऐसा एप्लिकेशन जो अपने स्वयं के कमांड लाइन इंटरफ़ेस के माध्यम से आदेश स्वीकार करता है।कमांड लाइन इंटरफ़ेस

संपादित करें: मुझे पहले से मेरी व्याख्या के बारे में माफ़ी मांगनी चाहिए, जाहिर है कि मैंने इसे समझाने में बहुत अच्छा काम नहीं किया है। एक और समय ...

मैं एक कमांड लाइन इंटरफ़ेस एप्लिकेशन बना रहा हूं जो उपयोगकर्ता से आदेश स्वीकार करता है। मेरे पास संकेतों को पकड़ने के लिए सिग्नल हैंडलर सेटअप है, जो तब एक ध्वज सेट करता है जिसे मुझे एप्लिकेशन को समाप्त करने की आवश्यकता होती है। मेरी समस्या यह है कि मैं जो कंसोल फ़ंक्शंस ढूंढ सकता हूं वह अवरुद्ध कर रहा है, जिसका अर्थ है कि मुझे यह पता नहीं लगाया जा सकता है कि मुझे अपने कंसोल प्रोसेसिंग लूप से बाहर निकलने की आवश्यकता है जब तक कि उपयोगकर्ता कुंजी दबाए (या फ़ंक्शन के आधार पर दर्ज करें))।

क्या कोई मानक तरीका है जो मैं गैर-ब्लॉक कंसोल इंटरैक्शन कर सकता हूं, या प्रोग्राम को ढूढ़ने का एक शानदार तरीका है ताकि अगर मैं सिग्नल थ्रेड से समाप्त हो जाऊं, तो सब कुछ ठीक से संभाला जाएगा और ठीक से जारी किया जाएगा (कृपया इसे गलत तरीके से समझें, मुझे पता है कि यह सिग्नलिंग थ्रेड से संसाधनों को लॉक करने और रिलीज़ करने के द्वारा कैसे किया जा सकता है, लेकिन यह गन्दा हो सकता है, इसलिए मैं इसे टालना चाहूंगा)

उम्मीद है कि स्पष्टीकरण अधिक समझ में आता है ...

उत्तर

6

* nix पर, आप कर सकते हैं एक संकेत हैंडलर रजिस्टर करने के लिए signal समारोह का उपयोग करें:


#include <signal.h> 

void signal_handler(int sig) 
{ 
    // Handle the signal 
} 

int main(void) 
{ 
    // Register the signal handler for the SIGINT signal (Ctrl+C) 
    signal(SIGINT, signal_handler); 
    ... 
} 

अब, जब भी किसी को Ctrl + C मारता है, अपने सिग्नल हैंडलर बुलाया जाएगा।

0

* * निक्स आधारित सिस्टम पर आपको काम करने के लिए वास्तव में सिग्नल हैंडलर की आवश्यकता नहीं हो सकती है। आप निर्दिष्ट कर सकता है कि आप SIGINT कॉल

int main(void) 
{ 
    // Register to ignore the SIGINT signal (Ctrl+C) 
    signal(SIGINT, SIG_IGN); 

    while(1) 
    { 
    retval = my_blocking_io_func(); 
    if(retval == -1 && errno == EINTR) 
    { 
     // do whatever you want to do in case of interrupt 
    } 
    } 
} 

महत्वपूर्ण तरीका है कि इस काम करता है अनदेखा करना चाहते पहचान करने के लिए है कि गैर अवरुद्ध कार्यों बाधित प्राप्त करते हैं। आम तौर पर, आपको एहसास होगा कि अवरुद्ध कार्य विफल रहा है (उदा। पढ़ें()) और फ़ंक्शन को पुनः प्रयास करें। यदि यह कुछ अन्य मूल्य था तो आप उचित त्रुटि से संबंधित कार्रवाई करेंगे।

8

ठीक है - यह विंडोज & पर मेरे लिए काम कर रहा है पोर्टेबल है - #ifdef SIGBREAK पर ध्यान दें - यह मानक संकेत नहीं है।

#include <csignal> 
#include <iostream> 
#include <ostream> 
#include <string> 
using namespace std; 

namespace 
{ 
    volatile sig_atomic_t quit; 

    void signal_handler(int sig) 
    { 
     signal(sig, signal_handler); 
     quit = 1; 
    } 
} 

int main() 
{ 
    signal(SIGINT, signal_handler); 
    signal(SIGTERM, signal_handler); 
#ifdef SIGBREAK 
    signal(SIGBREAK, signal_handler); 
#endif 
    /* etc */ 

    while (!quit) 
    { 
     string s; 
     cin >> s; 
     cout << s << endl; 
    } 
    cout << "quit = " << quit << endl; 
} 
+1

नोट: Windows पर, बंद करें बटन पर क्लिक करें sig कोड 'SIGBREAK' (बढ़ा देंगे Ctrl- टूटना) – 56ka

0

एक बेहतर * nix समाधान है कि धागा सुरक्षित है संकेत के बजाय pthread_sigmask() उपयोग करने के लिए है()।
उदाहरण के लिए, यह आप कैसे Signore SIGINT, SIGTERM, और वर्तमान धागा और भविष्य में SIGPIPE पैदा धागे है:

sigset_t waitset; 
sigemptyset(&waitset); 
sigaddset(&waitset, SIGINT); 
sigaddset(&waitset, SIGTERM); 
sigaddset(&waitset, SIGPIPE); 
pthread_sigmask(SIG_BLOCK, &waitset, NULL);