2010-12-07 11 views
2

私はC++、Linux環境でプログラミングしています。私はどのように非同期の方法で一定の間隔の後、また一定の間隔で関数を呼び出すことができますか?ブーストタイマーがhttp://www.boost.org/doc/libs/1_40_0/doc/html/boost_asio/tutorial/tuttimer2.htmlにあります。しかし、コールバックを呼び出すためにio.run()を呼び出す必要があります。コールバックを呼び出すと、関数を呼び出すために経過時間を処理する必要があるという元の問題に戻ります。私が必要とするのは、C#System.Threading.Timerのようなもので、指定された時間の後に渡された関数を呼び出すものです。タイム・ファンクション・コール

私は、関数呼び出しごとにスレッドを作成することを考えています。しかし、私はかなりの数のタイマーコールバックを持っています。したがって、私はそのようなスレッドを作成するためには高価になるか、私は他のオプションがあるのでしょうか?

ありがとうございました。

+0

あなたのインターバルはどれくらい短いですか? –

答えて

0

イベントループのためにglib--またはQtに切り替えて、それを使用してコードを書き込んでください。

+0

またはlibeventなどがあります。 –

+1

確かに、もしあなたがC.に落ちたいのであればもっとたくさんあります。 –

5

asio io_serviceは、のスケジュールのタイマーイベントを実行すると、適切なタイミングでコールバックします。ここで

は完全な例である:

#include <iostream> 
#include <boost/asio.hpp> 
#include <boost/bind.hpp> 

using namespace std; 

class timed_class 
{ 
public: 
    timed_class(boost::asio::io_service& io_service) : _timer(io_service) 
    { 
    // now schedule the first timer. 

    _timer.expires_from_now(boost::posix_time::milliseconds(100)); // runs every 100 ms 
    _timer.async_wait(boost::bind(&timed_class::handle_timeout, this, boost::asio::placeholders::error)); 
    } 

    void handle_timeout(boost::system::error_code const& cError) 
    { 
    if (cError.value() == boost::asio::error::operation_aborted) 
     return; 

    if (cError && cError.value() != boost::asio::error::operation_aborted) 
     return; // throw an exception? 

    cout << "timer expired" << endl; 

    // Schedule the timer again... 
    _timer.expires_from_now(boost::posix_time::milliseconds(100)); // runs every 100 ms 
    _timer.async_wait(boost::bind(&timed_class::handle_timeout, this, boost::asio::placeholders::error)); 
    } 

private: 
    boost::asio::deadline_timer _timer; 
}; 


int main(void) 
{ 
    boost::asio::io_service io_service; 

    timed_class t(io_service); 

    io_service.run(); 

    return 0; 
} 

EDIT:タイムアウトが経過した後に別のスレッドで派遣する、

boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service)); 

代わりのio_service.run();、今メインスレッドは継続となり、 io_servicehandle_timeout

+0

あなたの返事をありがとう。私の質問は、メインスレッドでio_service.run()を呼び出す必要があります。しかし、timed_class t(io_service)とio_service.run()の間のコードでは、他のタスクを実行する必要があります。最初にio_service.run()を呼び出すと、タスクを実行する前に遅延を待つことになります。 io_service.run()の前にタスクを実行する関数を呼び出すと、適切な時間にio_service.run()を呼び出すためにタスクが完了するのに必要な時間を知る必要がありますが、これは私の最初の問題です。だからいずれの方法でも私の問題は解決しない。または私は何かを逃していますか?ありがとう。 – Ashley

+0

@Ashley、 'io_service :: run()'は* dispatch *イベントをブロックしていますが、定期的に実行する必要があるコードの前にいくつかの設定が必要な場合は、まず 'run () 'を呼び出して定期的に' handle_timer'関数を呼び出します。 *実行するコードが*定期的に呼び出される必要があるコードの場合は、 'timed_class'の関数にそのコードを入れ、それをctorと' handle_timeout'本体で呼び出します。あなたが達成したいもののいくつかの擬似コードを入れれば、より良いかもしれません... – Nim

+0

あなたの返事をありがとう。ベースケースを提供しましょう。私がfunctionAを300 ms後に1回だけ呼び出す必要があるとしましょう。私は、正確に300ms(T1)の後、それを呼び出すいくつかのタイマーコールバックにfunctionAを渡したいと思います。これはTokenMacGuyのソリューションが提供したものと同じものです。現在の時刻(T0)で、io_service :: run()を呼び出すと、(T1)までブロックされます。これは、メインスレッドをブロックしたくないので望ましくありません。後でio_service :: run()を呼び出すと、ちょうど300ms後に300ms後に関数を呼び出すという元の問題であると推定できませんでした。 – Steveng

1

最も簡単な解決策の擬似コード:

を呼び出します。
function doThis() { 
    // your code here 
} 

function threadHandler() { 
    sleep(SecondsUntilTime); 
    doThis(); 
} 

function main() { 
    anotherthread = thread_create(threadHandler); 

    // more code here 

    join(anotherthread); 
    exit(); 
} 
関連する問題