2012-04-13 29 views
11

Tôi có một ứng dụng được viết để sử dụng boost::asio độc quyền làm nguồn dữ liệu đầu vào vì hầu hết các đối tượng của chúng tôi đều dựa trên mạng truyền thông. Do một số yêu cầu cụ thể, bây giờ chúng tôi yêu cầu khả năng sử dụng bộ nhớ dùng chung làm phương thức nhập liệu. Tôi đã viết thành phần bộ nhớ chia sẻ và nó hoạt động tương đối tốt.Boost :: asio, Shared Memory và Interprocess Communication

Vấn đề là cách xử lý thông báo từ quá trình chia sẻ bộ nhớ đến ứng dụng tiêu thụ dữ liệu có sẵn để đọc - chúng tôi cần xử lý dữ liệu trong chuỗi đầu vào hiện có (sử dụng boost::asio) và chúng tôi cũng cần không chặn luồng đầu vào đó đang chờ dữ liệu.

Tôi đã thực hiện điều này bằng cách giới thiệu một chuỗi trung gian chờ các sự kiện được báo hiệu từ quá trình nhà cung cấp bộ nhớ chia sẻ, sau đó đăng trình xử lý hoàn thành vào chuỗi đầu vào để xử lý việc đọc dữ liệu. Điều này cũng đang hoạt động, nhưng việc giới thiệu chuỗi trung gian có nghĩa là trong một số lượng lớn trường hợp chúng ta có thêm một chuyển ngữ cảnh trước khi chúng ta có thể đọc dữ liệu có tác động tiêu cực đến độ trễ, và chi phí của chủ đề bổ sung cũng tương đối đắt tiền.

Dưới đây là một ví dụ đơn giản về những gì các ứng dụng được thực hiện:

#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); 
    } 
} 

Có cách nào để có được các dữ liệu xử lý trong input_thread trực tiếp (mà không cần phải post nó trong qua interrupt_thread Giả định là thread gián đoạn hoàn toàn được điều khiển bởi timings từ một ứng dụng bên ngoài (thông báo rằng dữ liệu có sẵn thông qua semaphore) cũng như giả định rằng chúng ta có toàn quyền kiểm soát cả các ứng dụng tiêu thụ và cung cấp, rằng chúng ta có các đối tượng bổ sung cần xử lý đối tượng input_thread (vì vậy chúng tôi không thể đơn giản chặn và chờ đối tượng semaphore ở đó). al là giảm chi phí, sử dụng CPU và độ trễ của dữ liệu đến thông qua ứng dụng cung cấp bộ nhớ chia sẻ.

+2

Nếu bạn đang sử dụng * NIX, cách tiếp cận dễ nhất là sử dụng đường ống UNIX để thông báo, vì vậy một đầu của đường ống được thêm vào 'input_thread' như một ổ cắm thông thường. Bạn vẫn phải chịu phí đồng bộ vv, nhưng lưu một bản sao dự phòng (đến/từ bộ đệm ổ cắm). Bạn có thể gửi bù đắp và chiều dài trên socket, và sau đó chỉ số shmem trực tiếp. – Useless

+0

Trong Windows, bạn có thể sử dụng windows :: object_handle để không đồng bộ chờ trực tiếp trên đối tượng đồng bộ hóa của bạn. –

Trả lời

1

Tôi đoán bạn đã tìm thấy câu trả lời của bạn kể từ khi bạn đăng câu hỏi này, đây là cho người khác hưởng lợi ...

thử và kiểm tra tăng strands.

Nó cung cấp cho bạn khả năng chọn chuỗi bạn muốn thực hiện một số công việc.

Nó sẽ tự động được xếp hàng đợi trên chuỗi cụ thể, đó là điều bạn sẽ không phải suy nghĩ.

Nó thậm chí còn cung cấp cho bạn một trình xử lý hoàn thành nếu bạn cần biết khi nào công việc được thực hiện.

Các vấn đề liên quan