2011-06-15 14 views
5

मैं नियंत्रण-सी ईवेंट को कैसे प्रबंधित करूं या अपना बूस्ट :: एएसओ सर्वर रोकूं। मेरे पास एक tcp & udp संयुक्त सर्वर है और जब मैं ctrl-c दबाता हूं तो साफ़ रूप से बाहर निकलने में सक्षम होना चाहता हूं। मुझे अनचाहे नियंत्रण-सी के लिए पहला मौका अपवाद मिलता है। यहाँ मेरी कोडएक बूस्ट टीसीपी/udp सर्वर में नियंत्रण-सी को कैसे संभालना है

void startTCP() 
{ 
    http::syncServer::server serv(2); 

// Set console control handler to allow server to be stopped. 
// console_ctrl_function = boost::bind(&http::syncServer::server::stop, &serv); 
//SetConsoleCtrlHandler(console_ctrl_handler, TRUE); 
// Run the server until stopped. 
serv.run(); 
} 


void startUDP() 
{ 
    boost::asio::io_service io_service; 
    http::syncServer::udp_server server(io_service); 
// console_ctrl_function = boost::bind(&http::syncServer::udp_server::stop, &server); 
// SetConsoleCtrlHandler(console_ctrl_handler, TRUE); 
io_service.run(); 
} 

int main(int argc, char* argv[]) 
{ 
    try 
    { 
    boost::shared_ptr<boost::thread> tcpThread(new boost::thread(startTCP)); 
    boost::shared_ptr<boost::thread> udpThread (new boost::thread(startUDP)); 

    /*console_ctrl_function = boost::bind(&http::syncServer::udp_server::stop, &server); 
    SetConsoleCtrlHandler(console_ctrl_handler, FALSE);*/ 

    tcpThread->join(); 
    udpThread->join(); 
} 
catch (std::exception& e) 
{ 
    std::cerr << "exception: " << e.what() << "\n"; 
} 

return 0; 
} 
+1

[मानक तरीका के संभावित डुप्लिकेट की तरह Boost.Asio साथ एक साफ बंद प्रदर्शन करने के लिए asio से signal_set उपयोग कर सकते हैं ] (http://stackoverflow.com/questions/4639909/standard-way-to-perform-a-clean-shutdown-with-boost-asio) – CharlesB

उत्तर

4

सी मानक पुस्तकालय शामिल <signal.h> (जैसे see here), जिसके साथ आप SIGINT (Ctrl-C) के लिए एक संकेत हैंडलर रजिस्टर कर सकते हैं। यह चाल चलाना चाहिए, मान लीजिए कि आपका मंच सिग्नल का समर्थन करता है।

आप सिगटरएम के लिए एक हैंडलर को भी मारने के लिए कृपापूर्वक जवाब देने के लिए पंजीकरण करना चाहते हैं (1) ed।

#include <signal.h> // or <csignal> in C++ 

void ctrlchandler(int) { /*...*/ WE_MUST_STOP = 1; } 
void killhandler(int) { /*...*/ WE_MUST_STOP = 2; } 

int WE_MUST_STOP = 0; 

int main() { 
    signal(SIGINT, ctrlchandler); 
    signal(SIGTERM, killhandler); 
    /* ... */ 

    // e.g. main loop like this: 
    while(pump_loop() && 0 == WE_MUST_STOP) { } 

} 

सैम मिलर द्वारा सुझाव दिया गया है, मान लीजिए आपका मुख्य पाश कुछ m_io_service.run() के साथ एक एकल-थ्रेड boost.asio पाश है। फिर वैश्विक झंडे के बजाय आप (m_io_service मानते हैं) post सिग्नल हैंडलरों के भीतर से आईओ सेवा के लिए एक स्टॉप हैंडलर।

+0

एक पूर्ण उत्तर होने के लिए आपको चाहिए सुझाव दें कि सिग्नल हैंडलर के भीतर से 'io_service' इवेंट लूप को कैसे रोकें। –

+0

ठीक है, मैंने उस अंत में एक टिप्पणी जोड़ दी है, और मैंने मुख्य उदाहरण में एक कच्ची ध्वज-आधारित स्टॉप स्थिति जोड़ा है। यह देखते हुए कि ओपी अलग-अलग धागे में एएसआईओ आईओ सेवाओं को चलाने के लिए चाहता है, मुझे लगता है कि उसके पास कहीं भी अपना समर्पित मुख्य लूप होगा। –

4

बढ़ावा 1.47 के रूप में आप asio से signal_set उपयोग कर सकते हैं:

class Server { 
public: 
    Server(...) { 
    _signals.add(SIGINT); 
    _signals.add(SIGTERM); 
    _signals.async_wait(bind(&Server::handle_stop, this)); 

    } 
    void handle_stop() { 
    // do what you need to kill the Server - usually you just have to cancel all waits (incl deadline_timers), which will make the io_service exit gracefully 
    } 
private: 
    boost::asio::signal_set _signals; 
}; 

खबरदार, उदा का बढ़ावा संस्करणों नवीनतम उबंटू 1.46 है - इसलिए यह खून बह रहा है (प्राइमो 2012)।

चीयर्स,

माइकल

+0

इस उत्तर के साथ समस्याएं। ए: सिग्नल_सेट कन्स्ट्रक्टर को io_service के संदर्भ की आवश्यकता है। बी: हैंडल_स्टॉप हस्ताक्षर गलत है। – ravenspoint

0

आप इस

// stop on ctrlC signal 

boost::asio::signal_set signals(
    io_service, 
    SIGINT, 
    SIGTERM); 
signals.async_wait(
    boost::bind(
     &boost::asio::io_service::stop, 
     &io_service)); 

The docs are here

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^