2011-12-15 4 views
5

में असिंक्रोनस प्रोसेसिंग एक सर्वर जो हमेशा के लिए चलाएगा और प्रक्रियाओं को संसाधित करेगा, उसमें कोड के असीमित भाग की आवश्यकता होगी जो कुछ डेटाबेस प्रश्नों को निष्पादित करेगा और केवल तभी अपडेट होगा जब इसमें कोई नया बदलाव हो। सर्वर को हमेशा के लिए चलना पड़ता है और एक डीबी फ़ंक्शन निष्पादित करने के लिए इस फ़ंक्शन को बार-बार चलाना पड़ता है, ताकि प्रत्येक 'x' मिनट में एक बार अद्यतन की वजह से सर्वर में बाधा न हो।सी ++

सी ++ में असीमित रूप से इसे कैसे संसाधित किया जा सकता है? मैं डेमॉन पर चलाने के लिए अकेले उस फ़ंक्शन को कैसे सेट कर सकता हूं ताकि यह सर्वर को अवरुद्ध न करे?

+0

एक बहु थ्रेडेड प्रोग्राम के बारे में कैसे? –

+6

क्या आपने बूस्ट एएसआईओ की जांच की है? सिंक्रोनस और एसिंक्रोनस आईओ, टाइमर और बहुत कुछ हैं। एक थ्रेडेड दृष्टिकोण का उपयोग करने के लिए http://www.boost.org/doc/libs/release/libs/asio/ – Joel

+0

। क्या मैं उस थ्रेड को डिमन पर सेट कर सकता हूं जैसे कि यह पाइथन में कैसे किया जाता है? क्योंकि बाकी कार्यक्रम को वास्तव में कोर्बा के रूप में धागे की आवश्यकता नहीं है। @ जोएल एएसआईओ में आ रहा है, कृपया मुझे प्रबुद्ध करें। यह एक अच्छा विकल्प जैसा दिखता है (मुझे एएसओ का बहुत कम ज्ञान है) लेकिन ऐसा लगता है कि io_service.run() में अवरुद्ध कॉल है। मैं समय-समय पर dbqueries के लिए फ़ंक्शन को अतुल्यकालिक रूप से चलाने के लिए चाहता हूं इससे कोई फर्क नहीं पड़ता कि सर्वर क्या करता है। वे एक चर को साझा करने जा रहे हैं, सिवाय इसके कि वे बहुत अलग हैं। जबकि सर्वर चल रहा है, अन्य फ़ंक्शन को असीमित रूप से चलाना है। – King

उत्तर

5

मैं दृढ़ता से Boost's ASIO पुस्तकालय

का उपयोग कर की सलाह देते हैं आप नए अनुरोधों और एक अन्य समय पर अपडेट जांचने के लिए स्वीकार करने के लिए एक वर्ग की जरूरत होगी। दोनों अपने काम को असीमित रूप से कर सकते हैं और कार्य को शेड्यूल करने के लिए उसी बूस्ट :: asio :: io_service का उपयोग कर सकते हैं।

सेटअप

  • एक नेटवर्क अतुल्यकालिक boost::asio::ip::tcp::acceptor नए अनुरोधों के लिए सुन होगा।
  • boost::asio::deadline_time एक असीमित प्रतीक्षा करें डेटाबेस के अपडेट के लिए जांच करें।

छद्म मैं क्या समझते हैं कि आप का वर्णन कर रहे हैं के लिए कोड के नीचे है:

#include <iostream> 
#include <boost/asio.hpp> 
#include <boost/bind.hpp> 
#include <boost/shared_ptr.hpp> 
#include <string> 

class DatabaseUpdateChecker{ 
    public: 
    DatabaseUpdateChecker(boost::asio::io_service& io, const int& sleepTimeSeconds) 
    :timer_(io,boost::posix_time::seconds(sleepTimeSeconds)),sleepSeconds_(sleepTimeSeconds){ 
     this->timer_.async_wait(boost::bind(&DatabaseUpdateChecker::doDBUpdateCheck,this,boost::asio::placeholders::error)); 
    }; 

    protected: 
    void doDBUpdateCheck(const boost::system::error_code& error){ 
     if(!error){ 
      std::cout << " Checking Database for updates" << std::endl; 
      //Reschdule ourself 
      this->timer_.expires_at(timer_.expires_at() + boost::posix_time::seconds(this->sleepSeconds_)); 
      this->timer_.async_wait(boost::bind(&DatabaseUpdateChecker::doDBUpdateCheck,this,boost::asio::placeholders::error)); 
     } 
    }; 
    private: 
    boost::asio::deadline_timer timer_; 
    int sleepSeconds_; 
}; 

typedef boost::shared_ptr<boost::asio::ip::tcp::socket> TcpSocketPtr; 

class NetworkRequest{ 
    public: 
    NetworkRequest(boost::asio::io_service& io, const int& port) 
    :acceptor_(io,boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(),port)){ 
     this->start_accept(); 
    }; 
    protected: 
    void start_accept(){ 
     TcpSocketPtr socketPtr(new boost::asio::ip::tcp::socket(acceptor_.get_io_service())); 
     std::cout << "About to accept new connection" << std::endl; 
     acceptor_.async_accept(*socketPtr,boost::bind(&NetworkRequest::handle_accept,this,socketPtr,boost::asio::placeholders::error)); 
    }; 
    void handle_accept(TcpSocketPtr socketPtr,const boost::system::error_code& error){ 
     std::cout << "Accepted new network connection" << std::endl; 
     if(!error){ 
      std::string response("This is a response\n"); 
      boost::asio::async_write(*socketPtr,boost::asio::buffer(response), 
       boost::bind(&NetworkRequest::handle_write,this,boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred)); 
     } 
     //Start listeing for a new connection 
     this->start_accept(); 
    } 
    void handle_write(const boost::system::error_code& error,size_t size){ 
     if(!error){ 
      std::cout << "Wrote out " << size << " bytes to the network connection" << std::endl; 
     } 

    } 
    private: 
    boost::asio::ip::tcp::acceptor acceptor_; 
}; 

int main(int argc, char *argv[]) { 
    static const int DB_TIMER_SECONDS=5; 
    static const int LISTENING_TCP_PORT=4444; 

    std::cout << "About to start" << std::endl; 
    boost::asio::io_service io; 

    DatabaseUpdateChecker dbChecker(io,DB_TIMER_SECONDS); 
    NetworkRequest networkRequestAcceptor(io,LISTENING_TCP_PORT); 

    io.run(); 

    std::cout << "This won't be printed" << std::endl; 
    return 0; 
} 

ऊपर संकलन और यह है कि डाटाबेस अद्यतन परीक्षक अद्यतन के लिए हर 5 सेकंड की जाँच करेगा दर्शाएंगे जबकि पर कनेक्शन के लिए सुन चल टीसीपी पोर्ट 4444. कोड को एक नया कनेक्शन स्वीकार करने के लिए आप टेलनेट/नेटकैट/अपने पसंदीदा नेटवर्क क्लाइंट टूल का उपयोग कर सकते हैं ....

telnet 127.0.0.1 4444 
Trying 127.0.0.1... 
Connected to localhost. 
Escape character is '^]'. 
This is a response 
Connection closed by foreign host. 

आप पाते हैं कि अद्यतन और/या अनुरोध के प्रसंस्करण के लिए समय की एक महत्वपूर्ण राशि लेता है तो मैं अपने आवेदन सूत्रण और उसके अपने सूत्र में प्रत्येक कार्य चल रहा है इस पर गौर चाहते हैं। io_service शेड्यूल करेगा कि उसे क्या करना है और पूरा नहीं होने तक पूरा नहीं हुआ है। यह चाल है कि कक्षाएं पूरी तरह से काम कर रही हों जब वे काम कर लें।

बेशक आपको अपने प्रश्न पर दूसरों की टिप्पणियों को ध्यान में रखना होगा। मैं नहीं जानता कि कैसे एक कॉरबा इंटरफ़ेस इसे जटिल कर सकता है लेकिन मुझे लगता है कि बूस्ट :: एसिओ एक एसिंक्रोनस सी ++ लाइब्रेरी के रूप में आपके द्वारा वर्णित एक अच्छा निर्णय और लचीला होगा।

+0

मैं बूस्ट एएसओ का उपयोग कर समाप्त हुआ। आपके द्वारा उपयोग किए जाने वाले समय सीमा टाइमर को लागू करें। इसकी सराहना करने में थोड़ी देर लग गई। सब कुछ कोर्बा के पीछे चला गया। तो इससे कोई फर्क नहीं पड़ता। सर्वर प्रक्रियाओं के अनुरोध के दौरान प्रोग्राम का असीमित हिस्सा अलग-अलग तरीके से काम करता है। धन्यवाद ! आप उन लोगों में से एक हैं जिन्होंने कल मुझे विश्वास दिलाया! एक आकर्षण काम करता है! boost :: asio में कई अनुरोधों को संभालने की एक शक्तिशाली क्षमता है जो मैं बहुत संदिग्ध था। – King

1

ऐसा लगता है कि इसका अर्थ यह है कि सिस्टम लगातार नेटवर्क अनुरोधों को संसाधित करता है, यह असीमित रूप से डीबी के साथ संचार करता है।

इसका क्या अर्थ है कि जब इसे डीबी से बात करने की आवश्यकता होती है तो यह एक प्रश्न भेजता है लेकिन प्रतिक्रिया की प्रतीक्षा नहीं करता है।

जब इसे डीबी से प्रतिक्रिया मिलती है तो यह प्रक्रिया करता है।

एसिंक्रोनस भाग को डीबी से बात करने वाले एक अलग थ्रेड के द्वारा कार्यान्वित किया जा सकता है और जब इसे प्रतिक्रिया मिलती है तो यह प्रोसेसिंग के लिए सर्वर कतार में भी पोस्ट करता है।

या सर्वर डेटा के लिए कई सॉकेट पर सुन सकता है और उनमें से एक डेटाबेस कनेक्शन हो सकता है जहां इसे डीबी से प्रतिक्रिया मिलती है।

+0

सर्वर क्वेरी नहीं भेजता है। इसके बजाय मैं टेबल को कैश करता हूं क्योंकि यह बहुत सीमित डेटा है। जिस समारोह को मैं इसे अतुल्यकालिक बनाना चाहता हूं वह कैशिंग करता है। इसलिए, जबकि कैशिंग असीमित रूप से होती है, सर्वर जारी रहता है। – King

1

तो मूल रूप से (यदि मैं आपको सही ढंग से समझता हूं) तो आपको यह देखने के लिए समय-समय पर डेटाबेस को मतदान करने की आवश्यकता है कि यह बदल गया है या नहीं। और जब यह बदल गया है, तो आपको एक कोर्बा-आधारित अनुरोध प्रोसेसर को सूचित करने की आवश्यकता है कि कोई बदलाव आया है।

मैं क्या करूँगा आपके कोर्बा सर्वर पर एक नया अनुरोध प्रकार जोड़ें। अनुरोध "डेटाबेस अद्यतन किया गया है"। फिर आप एक छोटा, पूरी तरह से अलग प्रोग्राम लिख सकते हैं जो केवल नौकरी है डेटाबेस को मतदान करना और डेटाबेस अद्यतन होने पर CORBA अनुरोध भेजना।

इस तरह, आप डेटाबेस अपडेट संदेश को कॉर्ब सर्वर के लिए मुख्य अनुरोध स्ट्रीम में जोड़ सकते हैं।

कोई धागा नहीं, कोई असीमित नहीं है। बस दो प्रक्रियाएं प्रत्येक अपनी खुद की चीज कर रही हैं।

+0

एक डेटाबेस को बार-बार मतदान करना और एक दूसरे के बीच गुज़रना अवरुद्ध होगा और समय की थोड़ी बर्बादी होगी। हर मिली सेकंड वास्तविक समय में कीमती है। हालांकि मैंने इस तरह की चीज को असंकालिक रूप से कार्यान्वित किया। अपडेट करने के लिए, मैं डीबी को मतदान करने जा रहा हूं यह देखने के लिए कि वास्तव में कोई बदलाव है या नहीं। – King

+0

@ डंब: तब मुझे समझ में नहीं आता कि आप क्या पूछ रहे थे। अगर आप डेटाबेस तालिका को बार-बार मतदान किए बिना बदल जाते हैं तो आप कैसे पता लगा सकते हैं? – Omnifarious

+0

सच है कि हमें डीबी मतदान करना है! आप जगह पर हैं लेकिन मैं जानना चाहता था कि क्या मैं एसिंक्रोनस रैपर के पीछे सब कुछ डाल सकता हूं। इसे एक अलग प्रक्रिया पर चलाना जो फिर से एक दूसरे के साथ कॉरबा पर बातचीत करेगा, मुझे समय पर थोड़ा सा अंतराल देता है। – King