2012-04-13 21 views
11

मेरे पास एक ऐसा एप्लिकेशन है जो boost::asio का उपयोग विशेष रूप से इनपुट डेटा के स्रोत के रूप में करने के लिए लिखा गया है क्योंकि हमारी अधिकांश वस्तुएं नेटवर्क संचार आधारित हैं। कुछ विशिष्ट आवश्यकताओं के कारण, अब हमें साझा मेमोरी को एक इनपुट विधि के रूप में उपयोग करने की क्षमता की आवश्यकता होती है। मैंने पहले से ही साझा स्मृति घटक लिखा है और यह अपेक्षाकृत अच्छी तरह से काम कर रहा है।बूस्ट :: एएसओ, साझा मेमोरी और इंटरप्रोसेस संचार

समस्या यह है कि साझा स्मृति प्रक्रिया से अधिसूचनाओं को उपभोग करने वाले अनुप्रयोग में सूचनाओं को कैसे प्रबंधित किया जाए, डेटा को पढ़ने के लिए उपलब्ध है - हमें मौजूदा इनपुट थ्रेड (boost::asio का उपयोग करके) में डेटा को संभालने की आवश्यकता है, और हमें भी उस इनपुट थ्रेड को डेटा के लिए प्रतीक्षा न करें।

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

यह अब भी काम कर रहा है, लेकिन मध्यवर्ती धागे की शुरूआत का मतलब है कि महत्वपूर्ण डेटा में हमारे पास एक अतिरिक्त संदर्भ स्विच है, इससे पहले कि हम डेटा को पढ़ सकें, जिसका विलंबता पर नकारात्मक प्रभाव पड़ता है, और ओवरहेड अतिरिक्त धागा भी अपेक्षाकृत महंगा है।

यहाँ आवेदन कर रहा है की एक साधारण उदाहरण है:?

#include <iostream> 
using namespace std; 

#include <boost/asio.hpp> 
#include <boost/thread.hpp> 
#include <boost/scoped_ptr.hpp> 
#include <boost/bind.hpp> 

class simple_thread 
{ 
public: 
    simple_thread(const std::string& name) 
     : name_(name) 
    {} 

    void start() 
    { 
     thread_.reset(new boost::thread(
     boost::bind(&simple_thread::run, this))); 
    } 

private: 
    virtual void do_run() = 0; 

    void run() 
    { 
     cout << "Started " << name_ << " thread as: " << thread_->get_id() << "\n"; 
     do_run(); 
    } 


protected: 
    boost::scoped_ptr<boost::thread> thread_; 
    std::string name_; 
}; 

class input_thread 
    : public simple_thread 
{ 
public: 
    input_thread() : simple_thread("Input") 
    {} 

    boost::asio::io_service& svc() 
    { 
     return svc_; 
    } 

    void do_run() 
    { 
     boost::system::error_code e; 
     boost::asio::io_service::work w(svc_); 
     svc_.run(e); 
    } 

private: 
    boost::asio::io_service svc_; 
}; 

struct dot 
{ 
    void operator()() 
    { 
     cout << '.'; 
    } 
}; 

class interrupt_thread 
    : public simple_thread 
{ 
public: 
    interrupt_thread(input_thread& input) 
     : simple_thread("Interrupt") 
     , input_(input) 
    {} 

    void do_run() 
    { 
     do 
     { 
     boost::this_thread::sleep(boost::posix_time::milliseconds(500)); 
     input_.svc().post(dot()); 
     } 
     while(true); 
    } 

private: 
    input_thread& input_; 
}; 

int main() 
{ 
    input_thread inp; 
    interrupt_thread intr(inp); 

    inp.start(); 
    intr.start(); 

    while(true) 
    { 
     Sleep(1000); 
    } 
} 

वहाँ किसी भी तरह से डेटा input_thread सीधे में संभाला प्राप्त करने के लिए है (post करने के लिए इसे interrupt_thread के माध्यम से में बिना इस धारणा है कि है इंटरप्ट थ्रेड पूरी तरह से बाहरी अनुप्रयोग से समय के द्वारा संचालित होता है (अधिसूचना कि डेटा एक सेमफोर के माध्यम से उपलब्ध है)। साथ ही, मान लीजिए कि हमारे पास उपभोग करने वाले और अनुप्रयोग प्रदान करने दोनों का कुल नियंत्रण है, हमारे पास अतिरिक्त ऑब्जेक्ट्स हैं जिन्हें संभालने की आवश्यकता है input_thread ऑब्जेक्ट (इसलिए हम वहां केवल सेमफोर ऑब्जेक्ट्स को ब्लॉक और इंतजार नहीं कर सकते हैं)। अल ओवरहेड, सीपीयू उपयोग और साझा स्मृति प्रदान करने के माध्यम से आने वाले डेटा की विलंबता को कम करने के लिए है।

+2

यदि आप * NIX पर हैं, तो सबसे आसान तरीका यूनिक्स पाइप को सूचित करने के लिए उपयोग करना है, इसलिए पाइप का एक छोर 'इनपुट_थ्रेड' में नियमित सॉकेट के रूप में जोड़ा जाता है। आप अभी भी सिंक्रनाइज़ेशन इत्यादि ओवरहेड लेते हैं, लेकिन एक अनावश्यक प्रतिलिपि (सॉकेट बफर से/से) को सहेजें। आप सॉकेट पर ऑफ़सेट और लम्बाई भेज सकते हैं, और उसके बाद सीधे शमेट को इंडेक्स कर सकते हैं। – Useless

+0

विंडोज़ में आप windows :: object_handle को एसिंक को सीधे अपने सिंक्रनाइज़ेशन ऑब्जेक्ट पर प्रतीक्षा करने में सक्षम हो सकते हैं। –

उत्तर

1

मुझे लगता है कि जब से तुम इस प्रश्न पोस्ट आप अपने जवाब मिल गया है, यह अन्य लोगों को लाभ के लिए है ...

कोशिश और बढ़ावा strands की जाँच करें।

यह आपको चुनने की क्षमता देता है कि आप किस थ्रेड पर कुछ काम करना चाहते हैं।

यह स्वचालित स्ट्रैंड पर स्वचालित रूप से कतारबद्ध हो जाएगा, ऐसा कुछ है जिसके बारे में आपको सोचना नहीं होगा।

यदि आपको यह पता होना चाहिए कि काम कब किया जाता है तो यह आपको एक पूरा करने वाला हैंडलर भी देता है।

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