0

次のスレッドプールがあります。

#include <queue>
#include <map>

#include <boost/shared_ptr.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/thread/thread.hpp>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp> // remove me (only for io)

class ThreadPool
{
    void run() {
        // get some work from a task queue and then work on it
    }
public:
    void work_as_mainthread(void) { m_io_service.run(); }

    ThreadPool(int poolSize = 4) : timer(m_io_service)
    {
        timer.expires_from_now(boost::posix_time::seconds(1));
        m_pWork.reset( new boost::asio::io_service::work(m_io_service) );

        for ( int i = 0; i < poolSize; ++i)
            m_threadGroup.create_thread( boost::bind(&boost::asio::io_service::run, &m_io_service) );
    }

private:
    boost::asio::io_service m_io_service;
    boost::asio::deadline_timer timer;
    boost::shared_ptr<boost::asio::io_service::work> m_pWork;
    boost::thread_group m_threadGroup;
};

int main()
{
    int n_threads = 2;
    ThreadPool pool(n_threads);
    // add some tasks here...
    pool.work_as_mainthread();
    return 0;
}

これは最小限の例であり、ここに完全なコードがあります。次のようにコンパイルします。

g++ -Wall -g -lboost_thread -lboost_date_time -lboost_system main.cpp -o main

async_wait() が呼び出されていないことに注意してください (なぜ必要なのかわかりません。スレッド プールはこれまでのところ機能しています)。

ここで、あるタスクが突然、別のタスクのタイムアウト前に別のタスクを実行したい場合があります。m_io_service にハンドラーをすぐに実行し (タイマーがまだ関係していなくても)、何も起こらなかったかのように続行するように指示する最良の方法は何ですか? まばらなドキュメントからは、実際にはわかりませんでした。

これはうまくいきませんでした:

timer.expires_at(boost::posix_time::microsec_clock::universal_time());
4

1 に答える 1

2

expires_at有効期限を設定するだけで、タイマーを「有効」にしないことに注意してくださいdealine_timer。したがって、タイマーに関連付けられた非同期操作はありません。これを完了ハンドラーとして呼び出す必要がありますasync_wait。タイムアウトが切れるか、タイマーがキャンセルされると、このハンドラーが関連するio_serviceのスレッドの 1 つで呼び出されます。

呼び出しio_service::postは とは無関係deadline_timerです。ファンクタをio_serviceキューにポストio_serviceし、スレッドの 1 つで可能な限りすぐに呼び出します。

于 2012-08-27T16:23:24.903 に答える