2011-11-02 5 views
13

मैं जीएनयू/लिनक्स पर दो प्रक्रियाओं के बीच संवाद करने के लिए एक पाइप का उपयोग कर रहा हूं। प्राप्त करने वाला अंत पाइप बंद कर देता है जबकि प्रेषण अंत अभी भी डेटा भेजने की कोशिश कर रहा है। यहां कुछ कोड है जो स्थिति को अनुकरण करता है।बूस्ट :: एएसओओ का उपयोग करते समय मैं सिगिपिप को कैसे रोकूं?

#include <unistd.h>                
#include <boost/asio.hpp>               

int main()                  
{                     
    int pipe_fds[2];            
    if(::pipe(pipe_fds) != 0) return 1;           
    // close the receiving end 
    ::close(pipe_fds[0]); 

    boost::asio::io_service io;            
    boost::asio::posix::stream_descriptor sd(io, pipe_fds[1]);  
    boost::system::error_code ec;             
    sd.write_some(boost::asio::buffer("blah"), ec); 

    return 0;                  
} 

जब मैं इसे चलाता हूं तो मुझे एक सिगिप मिलता है; क्लासिक स्थिति, मुझे पता है। हालांकि, मुझे लगता है कि boost::asio::error::basic_errors में broken_pipe मान है। मैं उम्मीद करता हूं कि सिग्नल उठाए बिना त्रुटि_code में वापस लौटाया जाएगा।

क्या यह मेरी प्रक्रिया के लिए सिगिप हैंडलर बनाने के बिना किया जा सकता है? उदाहरण के लिए, क्या :: Iio को बढ़ावा देने के लिए एक कॉन्फ़िगरेशन विकल्प है जो मुझे याद आ रही है? हो सकता है कि कुछ ऐसा जो कार्यान्वयन में MSG_NOSIGNAL को सक्षम करेगा?

+1

+1 प्रतिलिपि प्रस्तुत –

उत्तर

7

एक संकेत हैंडलर स्थापित SIGPIPE अनदेखी करने के लिए यदि आप उचित error_code

कोड देख सकते हैं और संकलन इच्छा

#include <unistd.h> 
#include <iostream> 
#include <boost/asio.hpp> 


int main(int argc, const char** argv) 
{ 
    bool ignore = false; 
    if (argc > 1 && !strcmp(argv[1], "ignore")) { 
     ignore = true; 
    } 
    std::cout << (ignore ? "" : "not ") << "ignoring SIGPIPE" << std::endl; 

    if (ignore) { 
     struct sigaction sa; 
     std::memset(&sa, 0, sizeof(sa)); 
     sa.sa_handler = SIG_IGN; 
     int res = sigaction(SIGPIPE, &sa, NULL); 
     assert(res == 0); 
    } 

    int pipe_fds[2]; 
    if(::pipe(pipe_fds) != 0) return 1; 
    // close the receiving end 
    ::close(pipe_fds[0]); 

    boost::asio::io_service io; 
    boost::asio::posix::stream_descriptor sd(io, pipe_fds[1]); 
    boost::system::error_code ec; 
    sd.write_some(boost::asio::buffer("blah"), ec); 

    if (ec) { 
     std::cerr << boost::system::system_error(ec).what() << std::endl; 
    } else { 
     std::cout << "success" << std::endl; 
    } 

    return 0; 
} 

[email protected] ~> g++ pipe.cc -lboost_system -lboost_thread-mt 
[email protected] ~> 

रन

[email protected] ~> ./a.out 
not ignoring SIGPIPE 
[email protected] ~> echo $? 
141 
[email protected] ~> ./a.out ignore 
ignoring SIGPIPE 
Broken pipe 
[email protected] ~> 

इस व्यवहार के लिए तर्क write(2) man page में है

EPIPE

fd एक पाइप या सॉकेट जिसका पढ़ने अंत बंद कर दिया है से जुड़ा है। जब ऐसा होता है तो लेखन प्रक्रिया को एक सिगिप सिग्नल भी प्राप्त होगा। (इस प्रकार, लिखने वापसी मान में देखा जाता है कार्यक्रम पकड़ता, ब्लॉक या इस संकेत पर ध्यान नहीं देता है, तो केवल।)

जोर मेरे द्वारा जोड़ा गया।

+0

+1 अच्छा व्यापक जवाब के लिए में कर के रूप में हमेशा :) – Ralf

+0

बहुत खराब, मुझे नहीं पता था कार्यान्वयन लिखने उपयोग कर रहा था है। मैंने आशा की थी कि वे प्रेषण का उपयोग कर रहे थे और मैं MSG_NOSIGNAL ध्वज को पार करने में सक्षम हो सकता था। उदाहरण कोड के लिए धन्यवाद। – kalaxy

+0

@kalaxy आप –

3

सिग्पिप ऑपरेटिंग सिस्टम द्वारा उत्पन्न होता है जब पाइप का एक छोर कनेक्ट नहीं होता है - आप वास्तव में इसे boost :: asio से नहीं रोक सकते हैं। हालांकि आप सिग्नल को केवल अनदेखा कर सकते हैं और बाकी को स्वयं का ख्याल रखना चाहिए।

2

signal_init फ़ाइल boost/asio/detail/signal_init.hpp

+1

भेजकर MSG_NOSIGNAL का उपयोग कर सकते हैं लेकिन ऐसा लगता है कि यह केवल कुछ प्लेटफ़ॉर्म के लिए ही करता है। दुर्भाग्यवश यह विशेष रूप से लिनक्स और ओएस एक्स पर बूस्ट 1.55.0 के रूप में शामिल नहीं है। – eregon

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

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