2012-04-13 2 views
11

대부분의 개체가 네트워크 통신 기반이므로 입력 데이터 소스로 boost::asio을 독점적으로 사용하도록 작성된 응용 프로그램이 있습니다. 몇 가지 특정 요구 사항으로 인해 공유 메모리를 입력 방법으로 사용할 수있는 기능이 필요합니다. 이미 공유 메모리 구성 요소를 작성했으며 비교적 잘 작동합니다.Boost :: 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

+0

Windows에서 windows :: object_handle을 사용하여 동기화 개체에서 비동기 대기를 직접 수행 할 수 있습니다. –

답변

1

이 다른 사람이 이익을위한 것입니다 ...

시도하고 부스트 strands을 확인하십시오.

일부 작업을 수행 할 스레드를 선택할 수 있습니다.

특정 가닥에 자동으로 대기열이 생깁니다. 생각할 필요가없는 내용입니다.

작업 완료 시점을 알아야 할 경우 완료 처리기도 제공됩니다.