2012-04-13 132 views
11

我有基于被写入到使用boost::asio仅仅作为其输入数据的源,因为大多数我们的对象的应用程序是网络通信。由于某些特定的要求,我们现在需要使用共享内存作为输入方法。我已经编写了共享内存组件,它工作得相当好。升压:: ASIO,共享内存和进程间通信

问题是如何处理从共享内存进程到消费应用程序的数据可供读取的通知 - 我们需要处理现有输入线程中的数据(使用boost::asio),而且我们还需要不阻止输入线程等待数据。

我已经通过引入到将要从所述共享存储器提供商处理用信号然后投递完成处理程序到输入线程来处理读取的数据的事件等待的中间螺纹实现这一点。

这也适用于现在,但引入中间线程意味着在大量情况下,我们有额外的上下文切换,然后才能读取对延迟产生负面影响的数据,以及附加线程也相对昂贵。

这里是什么样的应用程序在做一个简单的例子:?(不通过interrupt_thread在不必post

#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直接处理的数据的假设是,中断线程完全由来自外部应用程序的定时驱动(通知数据可通过信号量获得)并且,假设我们完全控制了消费应用程序和提供应用程序,我们还有其他对象需要处理input_thread对象(所以我们不能简单地阻塞并等待那里的信号量对象)。 al将减少通过共享内存提供应用程序进入的数据的开销,CPU利用率和延迟。

+2

如果你在* NIX,最简单的方法是使用UNIX管道通知,管这么一端被添加到'input_thread'作为一个普通插座。你仍然会产生同步等开销,但保存一个冗余副本(到/从套接字缓冲区)。您可以通过套接字发送偏移量和长度,然后直接为shmem编制索引。 – Useless 2012-12-03 10:19:29

+0

在Windows中,您可以使用windows :: object_handle来异步地直接在同步对象上等待。 – 2012-12-30 20:45:28

回答

1

我想你已经找到你的答案,因为你张贴了这个问题,这是对他人受益...

尝试,并检查了升压strands

它给你你想要做的一些工作,这线程选择的能力。

它会自动获得具体链排队,这东西你不会去想。

它甚至给你,如果你需要的时候工作完成知道完成处理。