线程+ boost::函数中的getline访问冲突



我打算写一个在线程中读取std::cin的类,并在输入某些内容时调用回调。回调是一个boost::function。如果我只有std::getline (std::cin, command);,代码就会运行,但是如果我添加if(this->m_receiveHandler != NULL)行,代码就会因"访问违规"而崩溃。我真的不知道发生了什么,所以我把问题简化为下面的测试。

这个问题不是完全确定的,有时我可以输入一两行,有时它立即崩溃。程序输出的最后一件事总是"access receiver handler"。

class InputReader
{
private:
    boost::function<void (const char*, unsigned int) > m_receiveHandler;
    boost::thread m_receiveThread;
    void receiveLoop(void)
    {
        while(true)
        {
            std::string command;
            std::getline (std::cin, command);
            std::cout << "access receiver handler" << std::flush;               
            if(this->m_receiveHandler != NULL)
            {
            }           
        }
    }
public:
    InputReader()
    {
        m_receiveThread = boost::thread(boost::bind(&InputReader::receiveLoop, this));
    }

};
TEST(InputReaderTest, WaitInfinite)
{
    InputReader reader;
    while (true) {};
}

你看到这段代码有什么问题吗?

编辑:我在Suse Linux上编译GCC 4.3.2与Boost 1.49。

我刚刚在OSX上尝试了clang,它可以工作(用std代替boost)。当您在不同的公共成员函数中启动线程时会发生什么?boost函数变量实际上是两个线程之间的共享变量,可能应该受到一些并发原语的保护。线程实际上可能会看到'this'对象的不完整快照。但它并没有解释为什么它在失败之前工作了两次。如果您知道receiveHandler将在构造时是什么,并且您不需要更改它,则可以选择将boost::函数作为参数传递给线程(复制甚至移动都可以)。

最新更新