3

長い話を短くするために、私のコード:

#include <iostream>
#include <map>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

namespace ba = boost::asio;
namespace bp = boost::posix_time;

typedef std::map<int, ba::deadline_timer*> timer_map;

timer_map g_timers;
boost::mutex g_timers_lock;

ba::io_service g_ios;

void on_timer(int id) {
    {
            boost::mutex::scoped_lock lock(g_timers_lock);
            timer_map::iterator it = g_timers.find(id);
            assert(it != g_timers.end());
            g_timers.erase(id);
    }

    // std::cout << "delete timer " << id << std::endl;
}

int main(void) {
    boost::thread trd(boost::bind(&ba::io_service::run, &g_ios));
    trd.detach();

    int count = 0;
    for (;;) {
            for (int i = 0; i < 100; i++) {
                    ba::deadline_timer* pt = new ba::deadline_timer(g_ios, bp::seconds(1));
                    pt->async_wait(boost::bind(&on_timer, count));

                    boost::mutex::scoped_lock lock(g_timers_lock);
                    g_timers.insert(std::make_pair(count++, pt));
            }

            usleep(20000);
    }

    return 0;
}

==================================

g_timersをロックする必要がありますが、g_iosをロックする必要がありますか?私はこれらの行を意味します:

ba::deadline_timer* pt = new ba::deadline_timer(g_ios, bp::seconds(1));
pt->async_wait(boost::bind(&on_timer, count));

スレッドセーフですか?g_iosを参照し、g_ios.add_job(this_timer)..etc ..を呼び出しますか?

4

1 に答える 1

2

あなたの質問に直接答えるために、はい、インスタンスio_serviceはスレッドセーフです。これについては、ドキュメントで説明されています。

スレッドセーフ

個別のオブジェクト:安全。

共有オブジェクトreset():および notify_fork()関数の特定の例外を除いて、安全です。run()未定義、、、または呼び出しがあるときにreset()を 呼び出すとrun_one()、未定義の動作が発生します。関数、またはに関連付けられているI / Oオブジェクト上の関数が別のスレッドで呼び出されている間は、関数を呼び出さないでください 。poll()poll_one()notify_fork()io_serviceio_service

しかし、あなたが何を達成しようとしているのかは私にはわかりません。書かれているようio_serviceに、呼び出したときに行う作業がないため、例は何も実行せず、io_service::run()すぐに戻ります。あなたは戻り値を無視しました、あなたがそれを調べたならば、それはゼロになると思います。

ミューテックスの使用にも疑問があります。一般に、非同期ハンドラー内から共有リソースにアクセスする必要がある場合は、ミューテックスではなくストランドを使用することをお勧めします。この概念は、スレッドの使用と同様に、Asioの例とドキュメントで非常によく説明されています。

于 2012-04-11T03:50:43.230 に答える