13

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ます(したがって、そこでセマフォオブジェクトを単純にブロックして待機することはできません)。目標は、オーバーヘッドを削減することです。共有メモリ提供アプリケーションを介して着信するデータのCPU使用率と遅延。

4

1 に答える 1

1

この質問を投稿して以来、あなたは答えを見つけたと思います。これは他の人の利益のためです...

ブーストストランドを試してみてください。

これにより、作業を行うスレッドを選択することができます。

特定のストランドで自動的にキューに入れられます。これについて考える必要はありません。

作業がいつ完了したかを知る必要がある場合は、完了ハンドラーも提供します。

于 2012-12-30T20:28:36.497 に答える