Boost:: asio, общая память и межпроцессная связь

У меня есть приложение, которое написано для использования 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 (поэтому мы не можем просто блокировать и ждать на объектах семафора). Цель состоит в том, чтобы уменьшить накладные расходы, загрузку процессора и задержку данных, поступающих через приложение для предоставления общей памяти.

Ответ 1

Я думаю, вы нашли свой ответ, так как вы разместили этот вопрос, это для других...

попробуйте и запустите boost strands.

Это дает вам возможность выбрать, на какой поток вы хотите выполнить некоторую работу.

Он автоматически попадет в очередь на конкретную цепочку, что вам не придется думать.

Он даже дает вам обработчик завершения, если вам нужно знать, когда работа выполнена.