线程同步-信号量-strand的用法总结

这里展示不用boost::asio::strand而是利用常规线程同步的手段来完成线程的同步。

 

#include <iostream>

#include <boost/asio.hpp>

#include <boost/thread.hpp>

#include <boost/thread/mutex.hpp>

#include <boost/bind.hpp>

#include <boost/date_time/posix_time/posix_time.hpp>

class printer

{

public:

    printer(boost::asio::io_service& io):

       timer1_(io, boost::posix_time::seconds(1)),

       timer2_(io, boost::posix_time::seconds(1)),

       count_(0)

    {

       timer1_.async_wait(boost::bind(&printer::print1, this));

       timer2_.async_wait(boost::bind(&printer::print2, this));

    }

    ~printer()

    {

       std::cout << "Final count is " << count_ << "/n";

    }

    void print1()

    {

       mutex_.lock();

       if (count_ < 10)

       {

           std::cout <<"ThreadID:" <<GetCurrentThreadId() <<" Timer 1: " << count_ << "/n";

           ++count_;

           timer1_.expires_at(timer1_.expires_at() + boost::posix_time::seconds(1));

           timer1_.async_wait(boost::bind(&printer::print1, this));

       }

       mutex_.unlock();

    }

    void print2()

    {

       mutex_.lock();

       if (count_ < 10)

       {

           std::cout <<"ThreadID:" <<GetCurrentThreadId() <<" Timer 2: " << count_ << "/n";

           ++count_;

           timer2_.expires_at(timer2_.expires_at() + boost::posix_time::seconds(1));

           timer2_.async_wait(boost::bind(&printer::print2, this));

       }

       mutex_.unlock();

    }

private:

    boost::asio::deadline_timer timer1_;

    boost::asio::deadline_timer timer2_;

    int count_;

    boost::mutex mutex_;

};

int main()

{

    boost::asio::io_service io;

    printer p(io);

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

    io.run();

    t.join();

    return 0;

}

 

这样的效果和原boost::asio的例5是差不多的,boost::asio除了支持原生的线程同步方式外还加入了新的asio::strand是有意义的,因为这两种方式还是有区别的。

1.     用mutex的方式阻塞的位置是已经进入printe函数以后,而strand是阻塞在函数调用之前的。

2.     相对来说,当大量的同样回调函数需要同步时,asio::strand的使用更为简单一些。

3.     用mutex的方式明显能够更加灵活,因为不仅可以让线程阻塞在函数的开始,也可以阻塞在中间,结尾。

4.     对于同步的对象来说,asio::strand就是对其支持的回调对象,mutex是对本身线程的一种同步。

 

基本上,两者是相辅相成的,各有用处,但是实际上,假如从通用性出发,从额外学习知识触发,个人感觉strand似乎是可有可无的,不知道有没有必须使用strand的情况。。。。

 

到此,asio文档中tutorial中的timer系列例子是结束了。其实这里展示的以asio基本原理为主,甚至都还没有接触到任何与网络相关的东西,但是,这些却是进一步学习的基础。。。。。。

补充:利用strand实现的话:


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

class printer
{
public:
printer(boost::asio::io_service& io)
    : strand_(io),
      timer1_(io, boost::posix_time::seconds(1)),
      timer2_(io, boost::posix_time::seconds(1)),
      count_(0)
{
    timer1_.async_wait(strand_.wrap(boost::bind(&printer::print1, this)));
    timer2_.async_wait(strand_.wrap(boost::bind(&printer::print2, this)));
}

~printer()
{
    std::cout << "Final count is " << count_ << "/n";
}

void print1()
{
    if (count_ < 10)
    {
      std::cout << "Timer 1: " << count_ << "/n";
      ++count_;

      timer1_.expires_at(timer1_.expires_at() + boost::posix_time::seconds(1));
      timer1_.async_wait(strand_.wrap(boost::bind(&printer::print1, this)));
    }
}

void print2()
{
    if (count_ < 10)
    {
      std::cout << "Timer 2: " << count_ << "/n";
      ++count_;

      timer2_.expires_at(timer2_.expires_at() + boost::posix_time::seconds(1));
      timer2_.async_wait(strand_.wrap(boost::bind(&printer::print2, this)));
    }
}

private:
boost::asio::strand strand_;
boost::asio::deadline_timer timer1_;
boost::asio::deadline_timer timer2_;
int count_;
};

int main()
{
boost::asio::io_service io;
printer p(io);
boost::thread t(boost::bind(&boost::asio::io_service::run, &io));
io.run();
t.join();

return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值