我正在学习如何在boost库中使用线程,在我的搜索过程中,我找到了以下代码:
struct count
{
count(int id) : id(id) {}
void operator()()
{
for (int i = 0; i < 10; ++i)
{
boost::mutex::scoped_lock
lock(io_mutex);
std::cout << id << ": " << i << std::endl;
}
}
int id;
};
int main(int argc, char* argv[])
{
boost::thread thrd1(count(1));
boost::thread thrd2(count(2));
thrd1.join();
thrd2.join();
return 0;
}
这个程序运行正常,但我的问题是,void
operator()()
函数的行为是什么?因为有两个线程,每个线程使用不同的值初始化计数。它的两个主要count
变量是单独创建的,因此每个变量的void operator()()
应该是不同的。但似乎void operator()()
对于两个线程都是相同的。此代码void operator()()
中的另一件事是不是从任何地方调用的,所以它是如何运行的?
有人可以解释一下这个功能里面发生了什么吗?
void operator()()
答案 0 :(得分:4)
这是一个棘手的语法。
boost::thread thrd1(count(1));
boost::thread thrd2(count(2));
在这两行中,operator()
是 NOT 直接调用。这里显示的count(n)
是构造函数。然后,使用“1”和“2”值构造的对象将传递给thread
个对象,然后在内部调用operator()
以在为此目的创建的不同线程上运行特定任务。
但是由于两个对象在其ctors中记住了不同的值(1/2),因此operator()
中的公共代码对id
字段的不同实际值进行操作。这就是操作员没有参数的原因:所有必需的参数在构造过程中都存储在'count'对象中。
顺便说一下。构造一个对象并调用operator()
,一行看起来像这样:
count(1)();
答案 1 :(得分:0)
C ++中运算符重载的语法是:
return-type operator operator-name(args); 示例:int operator +(int other) 这里的运营商名称是“+”。在你的情况下,它是“()”
现在,你有2个线程实例,每个实例都有自己的count实例。当线程调用operator()()时,它会读取特定线程实例的计数值,这就是为同一个运算符提供不同结果的原因
答案 2 :(得分:0)
这肯定有助于您阅读代码的上下文(并在此处为其他读者发布链接:))。
没有任何其他上下文可以帮助我,我猜这是对boost :: thread的新学习者的演示。我假设你知道线程是如何工作的 - 如果你是新手,this link是一个很好的初学者概念参考。
要打破它:
boost::thread thrd1(count(1));
boost::thread thrd2(count(2));
使用不同的ID创建两个线程。正如@quetzalcoatl所提到的,boost线程接受一个定义operator ()()
的函数对象,并在另一个线程中执行该运算符的内容。这意味着我们现在有3个线程 - 主执行线程和我们上面创建的2个线程。
thrd1.join();
thrd2.join();
主执行线程等待另外两个线程 join - 即完成其处理并向主线程指示它们已完成。当它们 join 时,线程终止(请注意,thrd1是一个boost线程对象 - 用于引用我们在幕后创建的实际线程,并且在堆栈结束之前可用。)
operator()()
是一种监控方式。哪个线程正在运行b。多少&#39; skipping-between-threads&#39;发生。在解释之前,让我们看看结果。它可能类似(但可能不完全):
1: 0
1: 1
2: 0
2: 1
2: 2
2: 3
1: 2 ...
所以程序(在这种情况下)运行两个线程#1循环,切换到线程#2,运行几个循环,回到#1并继续运行。 There is a reason两个线程不能同时进入循环 - boost scoped_lock抓住(外部)io_mutex,将其锁定以供该线程使用并继续运行直到scoped_lock对象被销毁并且io_mutex对象被释放。这意味着,当两个线程并行运行时,只有一个对象可以在&#34; scoped_lock&#34;之后访问该特定堆栈。调用
希望有所帮助。