3

この質問は次のとおりです 。C++11スレッドは仮想メンバー関数では機能しません

コメントで示唆されているように、前の投稿での私の質問は正しい質問ではないかもしれないので、ここに元の質問があります:

一定/動的な頻度(ソースによって異なり、たとえば10回/秒)でいくつかのソースを照会し、それぞれのキューにデータをプルするキャプチャシステムを作成したいと思います。ソースは固定されていませんが、実行時に追加/削除される場合があります。

一定の頻度でキューからプルしてデータを表示するモニターがあります。

では、この問題に最適なデザインパターンまたは構造は何ですか。

すべてのソースプーラーのリストを作成しようとしていますが、各プーラーはスレッドと指定されたプル機能を保持しています(プル機能はプーラーと相互作用する可能性があります。たとえば、ソースがドレインの場合、停止するように求められます。そのスレッドのプルプロセス。)

4

1 に答える 1

2

ソースを照会する操作がブロックされていない限り(またはそれらがたくさんある場合を除いて)、これにスレッドを使用する必要はありません。Producer同期または非同期(スレッド)ディスパッチのいずれかで機能するから始めることができます。

template <typename OutputType>
class Producer
{
    std::list<OutputType> output;

protected:
    int poll_interval; // seconds? milliseconds?
    virtual OutputType query() = 0;

public:
    virtual ~Producer();

    int next_poll_interval() const { return poll_interval; }
    void poll() { output.push_back(this->query()); }

    std::size_t size() { return output.size(); }
    // whatever accessors you need for the queue here:
    // pop_front, swap entire list, etc.
};

これで、これから派生して、各サブタイプProducerにメソッドを実装できます。queryコンストラクターで設定poll_intervalしてそのままにするか、を呼び出すたびに変更することができqueryます。ディスパッチメカニズムに依存しない、一般的なプロデューサーコンポーネントがあります。

template <typename OutputType>
class ThreadDispatcher
{
    Producer<OutputType> *producer;
    bool shutdown;
    std::thread thread;

    static void loop(ThreadDispatcher *self)
    {
        Producer<OutputType> *producer = self->producer;

        while (!self->shutdown)
        {
            producer->poll();
            // some mechanism to pass the produced values back to the owner
            auto delay = // assume millis for sake of argument
                std::chrono::milliseconds(producer->next_poll_interval());
            std::this_thread::sleep_for(delay);
        }
    }

public:
    explicit ThreadDispatcher(Producer<OutputType> *p)
      : producer(p), shutdown(false), thread(loop, this)
    {
    }

    ~ThreadDispatcher()
    {
        shutdown = true;
        thread.join();
    }

    // again, the accessors you need for reading produced values go here
    // Producer::output isn't synchronised, so you can't expose it directly
    // to the calling thread
};

これは、プロデューサーをスレッドで実行し、頻繁に要求された場合にポーリングする単純なディスパッチャーの簡単なスケッチです。生成された値を所有者に戻すことは表示されないことに注意してください。これは、それらにアクセスする方法がわからないためです。

また、シャットダウンフラグへのアクセスを同期していないことにも注意してください。おそらくアトミックであるはずですが、生成された値を使用して行うことを選択すると、暗黙的に同期される可能性があります。

この組織では、たとえばselect / pollループから、またはBoost.Asioやプロデューサーごとの期限タイマーなどを使用して、単一のスレッドで複数のプロデューサーにクエリを実行する同期ディスパッチャーを簡単に作成できます。

于 2012-05-17T14:07:29.053 に答える