1

我有一个简单的程序,它使用 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 和线程。IE:

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() 中也是如此。

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

4

3 回答 3

0

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

一个有效而另一个无效的原因可能是编译器在决定何时何地在函数中需要重新加载done. done但理论上,无论哪种情况,如果在第一次迭代中为假,则没有什么可以阻止编译器永远循环。

于 2013-05-08T15:32:38.193 回答
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 中的变量 done 都指向不同的地址,这就是为什么在 timer 中设置 done true 并不会结束 func1 的循环。

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

于 2013-05-08T16:38:33.803 回答
0

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

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

于 2013-05-08T16:40:02.433 回答