通过引用传递vs Pass by指针:提升线程和截止时间计时器

时间:2013-05-08 15:27:52

标签: c++ multithreading boost 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();
}

代码的迭代工作,但是我最初在main函数中定义了bool,通过引用传递给函数func1和thread。即:

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完成的确值为true,即使在func1()中也是如此。

有关为何发生这种情况的任何见解?

3 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

来自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中设置为true的结果不会结束func1的循环。

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

答案 2 :(得分:0)

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

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