1

Boost Threads と Asio (非同期入力/出力) を研究していて、いくつかの概念をまとめるために次の例を書きました。

class Worker {
  private:
    boost::asio::io_service&     m_ios;
    boost::asio::deadline_timer  m_timer;
    unsigned                     m_cycles;
    unsigned                     m_time2wait;
    std::string                  m_threadName;

  public:
    Worker(boost::asio::io_service& ios,
           unsigned cycles, unsigned time2wait, const std::string& name);
    ~Worker ();
    void start ();
    void run ();
    void stop ();
};


Worker::Worker (boost::asio::io_service& ios,
                unsigned cycles, unsigned time2wait, const std::string& name)
: m_ios(ios),
  m_timer(ios, boost::posix_time::seconds (1)),
  m_cycles(cycles),
  m_time2wait(time2wait),
  m_threadName(name)
{
  logMsg(m_threadName, "is starting . . . ");
}

Worker::~Worker()
{
  logMsg(m_threadName, "is ending . . . ");
}

void Worker::start()
{
  logMsg (m_threadName, "start was called");

  m_timer.expires_at (m_timer.expires_at () +
              boost::posix_time::seconds (m_time2wait));
  m_timer.async_wait (boost::bind (&Worker::run, this));
}

void Worker::stop()
{
}

void Worker::run()
{
  if (m_cycles > 0)
  {
    logMsg (m_threadName, "run # ", m_cycles);
    --m_cycles;
    m_timer.expires_at (m_timer.expires_at() +
                        boost::posix_time::seconds(m_time2wait));
    m_timer.async_wait(boost::bind(&Worker::run, this));
  }
  else {
    logMsg (m_threadName, "end of cycling");
  }
}

void run_threads (boost::asio::io_service& io_srv)
{
  Worker worker_1(io_srv, 5, 2, "worker 1");
  Worker worker_2(io_srv, 5, 4, "worker 2");
  worker_1.start();
  worker_2.start();

  boost::shared_ptr <boost::thread> worker_Thread_One (
    new boost::thread (boost::bind (&boost::asio::io_service::run, &io_srv)));

  boost::shared_ptr <boost::thread> worker_Thread_Two (
    new boost::thread(boost::bind(&boost::asio::io_service::run, &io_srv)));

  worker_Thread_One->join();
  worker_Thread_Two->join();
}

int main (int argc, char** argv)
{
  boost::asio::io_service ios;

  run_threads(ios);

  return 0;
}

私はいくつかのスレッドを並行して動作させようとしています。それぞれが特定のオブジェクトを介してその作業を行っています。この例はどうやら機能しているようですが、スレッドと Asio を混在させるのは間違っていると感じています (設計が悪い)。スレッドを Asio (複数のスレッドに対して 1 つの io_service) と連携させるのは正しい方法ですか?

スレッド オブジェクトと「ワーカー」オブジェクトはどのように「結合」されているのでしょうか? 彼らは私のようではないと思います。たとえば、2 つのオブジェクトと 2 つのスレッドをインスタンス化した場合、期待どおりの出力が得られます。2 つのオブジェクトと 1 つのスレッドをインスタンス化した場合、プログラムの出力は同じです。

(logMsg は、出力操作を同期するミューテックスを持つ単純な cout ラッパーです。)

4

2 に答える 2

0

あなたの例は正しいように見えますが、この場合はAsioを使用する必要はありません。io_serviceAsio +スレッドは、スレッドプールのワークキューとして使用する場合に最も役立ちます。io_service::postそのように使用したい場合は調べてください。

于 2012-06-03T02:17:51.607 に答える