【发布时间】:2020-07-31 05:53:28
【问题描述】:
我正在学习多线程和 Boost 库(尤其是 Asio),我很难理解以下代码的工作原理(根据 Boost.org 教程稍作修改)
#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread/thread.hpp>
#include <boost/bind.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_ << std::endl;
}
void print1()
{
if (count_ < 10)
{
std::cout << "Timer 1: " << count_ << std::endl;
++count_;
timer1_.expires_at(timer1_.expires_at() + boost::posix_time::seconds(2));
timer1_.async_wait(boost::bind(&printer::print1, this));
}
}
void print2()
{
if (count_ < 10)
{
std::cout << "Timer 2: " << count_ << std::endl;
++count_;
timer2_.expires_at(timer2_.expires_at() + boost::posix_time::seconds(2));
timer2_.async_wait(boost::bind(&printer::print2, this));
}
}
private:
boost::asio::deadline_timer timer1_;
boost::asio::deadline_timer timer2_;
int count_;
};
void saysomething()
{
std::string whatyasay;
std::cin >> whatyasay;
std::cout << "You said " << whatyasay << std::endl;
}
int main()
{
boost::asio::io_service io;
printer p(io);
boost::thread t(boost::bind(&boost::asio::io_service::run, &io));
io.run();
std::cout << "Hey there\n";
t.join();
return 0;
}
这会导致以下输出
Timer 1: 0
Timer 2: 1
Timer 1: 2
Timer 2: 3
Timer 1: 4
Timer 2: 5
Timer 1: 6
Timer 2: 7
Timer 1: 8
Timer 2: 9
Hey there
Final count is 10
我对这段代码的期望是线程 t 将负责运行 io_service,这意味着其他操作可以同时进行。
相反,代码的行为与往常一样,也就是 io.run “阻塞”代码流,直到打印机对象内的计时器停止启动 async_waits,所以“嘿,那里”仅在计时器不再工作。
但这还不是全部:据我了解,只要有与之相关的工作(无论是工作对象,或者在本例中为计时器),调用 run() 方法后 io_services 就不会停止运行。话虽如此,既然线程与 io_service 相关联,我想知道为什么 io_service 首先会停止运行:毕竟,线程“链接”到 io_service 并继续自行运行;这显然与我一开始显然不明白这个线程在做什么的事实有关。
当我将“saysomething”方法添加到锅中时,事情变得更加复杂:我希望能够编写一些东西并打印该字符串,同时 2 个计时器继续工作。我使用的代码如下:
int main()
{
boost::asio::io_service io;
printer p(io);
boost::thread t(&saysomething);
io.run();
std::cout << "Hey there\n";
t.join();
return 0;
}
结果如下:
Timer 1: 0
Timer 2: 1
Timer 1: 2
Timer 2: 3
Timer 1: 4
Timer 2: 5
Timer 1: 6
Timer 2: 7
ghg //<--- my input
You said ghg
Timer 1: 8
Timer 2: 9
Hey there
Final count is 10
它工作正常,但是现在没有与 io_service 关联的线程,它最初的目的是什么?
总结我的三个问题是:
- 为什么不立即打印“Hey there”字符串,而不是等待 io_service 停止运行?
- 如果有线程链接到io_service,它究竟是如何停止运行的,这应该相当于io_service有工作要做?
- 由于线程不允许“代码流”向前移动,并且将所述线程链接到我的方法而不是 io_service 并没有导致任何错误,那么该线程最初的目的是什么?
【问题讨论】:
标签: c++ multithreading boost boost-asio