0

我对使用 boost 线程还很陌生。我几乎有一些东西正在运行,但遇到了一个绊脚石:任何帮助将不胜感激。

我有一个 VC++(VS2010 Windows 窗体)应用程序。在不久的将来,这需要移植到 C++ 和 Linux 上,所以我正在使用 boost 库来处理诸如线程之类的事情,以“简化”移植。

我在一个执行一些 i/o 的类中有一个工作函数:

void myClass::doIO{

    while (!boolKillthread){


    //do some work

    //sleep thread 
    boost::this_thread::sleep_for(boost::chrono::milliseconds(333));
    }
}

这是在增强线程中启动的:

boost::thread m_MyThread;
m_MyThread = boost::thread(boost::bind(&myClass::doIO));

这工作得很好,正在轮询 i/o 端口,并且正在完美地回调父类。但:

我有另一个函数需要在 doIO 线程上等待才能执行一些工作,所以我有一个函数,其代码如下:

while (myClass.IsWorkDone() == true){

    //hang a around a while

    //lines commented out below have been tried, but don't resolve the problem
    //boost::this_thread::yield();
    //boost::this_thread::sleep(boost::posix_time::milliseconds(50));
    //boost::this_thread::sleep_for(boost::chrono::milliseconds(50));

}

问题是,一旦我的代码进入 while 循环,boost 线程 doIO 就会停止 - 几乎就像它没有在自己的线程中运行一样!我已经尝试按照上面注释掉的行插入睡眠和产量,但无济于事。

有任何想法吗?


感谢大家的回复:是的,(伪代码)“IsWorkDone”只是返回一个变量,所以我理解(并且现在已经尝试过)使用 boost::mutex::scoped_lock 来更新该变量,所以我们有类似的东西

bool myWorkIsDone = false;

bool myClass::IsWorkDone{ return myWorkIsDone; }



void myClass::doIO{

    while (!boolKillthread){


    //do some work
    if (SomeCondition){
        boost::mutex::scoped_lock lock(myMutex);
        myWorkIsDone = true;
    }

    //sleep thread 
    boost::this_thread::sleep_for(boost::chrono::milliseconds(333));
    }
}

很好,但关键是(除非我遗漏了一些明显的东西,这很可能)当我的主代码在循环中时,线程似乎没有运行

而(myClass.IsWorkDone()==真){

    //hang a around a while

}

因为 IDE 通常会在 doIO 中的断点处停止,但在上述 while 循环中执行时不会。

实际上没有更多代码(相关)要添加 - 它应该很简单,但它不起作用!

4

1 回答 1

2

IsWorkDone看起来像什么?它看起来像这样吗:

 bool IsWorkDone() const { return workdone_; }

因为如果是这样,那就是你的问题。您需要使用互斥锁来包装对workdone_. 那是共享状态,共享状态需要互斥体。编译器可能正在读取循环顶部的变量,并且不再费心再次读取它。毕竟,据它所知,它根本没有理由改变,所以再读一遍也没有意义。

即使它再次读取它,CPU 也有一个很好的缓存行来保存它,它可能永远不会被刷新,所以你只是在读取它。

哦,当你设置它时,它也需要一个互斥锁。

让它成为一个::std::atomic<bool>实际上是一个更好的主意,但我猜你还没有。

于 2013-01-09T13:26:12.273 回答