繁体   English   中英

通过引用传递与通过指针传递:增强线程和截止时间计时器

[英]Pass by reference vs. Pass by pointer: Boost threads and deadline timer

我有一个简单的程序,使用boost库在1秒的范围内输出递增的整数:

#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/asio.hpp>
using namespace std;


void func1(bool* done)
{
    float i=0;
    while (!(*done))
    {
        cout << i << " ";
        i++;
    }
    return;
}

void timer(bool* done, boost::thread* thread)
{
    boost::asio::io_service io;
    boost::asio::deadline_timer timer(io, boost::posix_time::seconds(1));
    timer.wait();
    *done = true;
    return;
}

int main()
{
    bool done = false;

    boost::thread thread1(func1, &done);
    boost::thread thread2(timer, &done, &thread1);
    thread2.join();
    thread1.join();
}

该代码的迭代是有效的,但是我最初在主函数中定义的布尔值通过引用传递给函数func1和线程。 即:

void func1(bool& done) /*...*/ while (!(done))
/* ... */
void timer(bool& done, boost::thread* thread) /*...*/ done = true;

带有线程定义:

    boost::thread thread1(func1, done);
    boost::thread thread2(timer, done, &thread1);

当我像这样执行它时,func1()中的循环永远不会终止! 我在timer()返回处添加了一个断点,并且我的IDE(MS VC ++ Express 2010)表明,即使在func1()中,布尔值的确确实具有true值。

关于为什么发生这种情况的任何见解?

实际上,我不认为您的解决方案中的任何一种都是有效的,因为它们没有使用“原子”类型或其他机制来确保所做的done保持同步。

一个起作用而另一个不起作用的原因可能是编译器在确定函数何时何地需要重新加载done值时处理指针与引用的方式。 但是从理论上讲,无论哪种情况,如果第一次迭代中的done为假,则没有什么可以阻止编译器永远循环。

来自http://www.boost.org/doc/libs/1_53_0/doc/html/thread/thread_management.html#thread.thread_management.thread.multiple_argument_constructor

带参数的线程构造器

模板线程(F f,A1 a1,A2 a2,...);

前提条件:

 F and each An must by copyable or movable. Effects: As if thread(boost::bind(f,a1,a2,...)). Consequently, f and each an are copied into internal storage for access by the new thread. 

这里的关键词是“复制”。 在main,func1和timer中完成的变量都引用不同的地址,这就是为什么在timer中将done设置为true不会结束func1循环的原因。

我认为它与* done一起工作的原因是因为它正在复制地址,因此在各个函数中它是相同的。

要通过引用传递参数,请使用boost:ref

boost::thread thread1(func1, boost::ref(done));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM