【问题标题】:Pass by reference vs. Pass by pointer: Boost threads and deadline timer按引用传递与按指针传递:提升线程和截止时间计时器
【发布时间】:2013-05-08 15:27:52
【问题描述】:

我有一个简单的程序,它使用 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();
}

该代码的迭代有效,但是我最初将主函数中定义的 bool 通过引用传递给函数 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)表明 bool done 的值确实为 true,即使在 func1() 内也是如此。

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

【问题讨论】:

    标签: c++ multithreading boost timer


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

        来自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中的done变量都指向不同的地址,这就是为什么在timer中设置done为true并不会结束func1的循环。

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

        【讨论】:

          猜你喜欢
          • 2012-01-24
          • 1970-01-01
          • 1970-01-01
          • 2013-01-13
          • 2017-03-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多