在线程+ boost :: function中使用getline访问冲突

时间:2013-04-17 08:40:53

标签: c++ boost getline

我打算写一个在线程中读取std::cin的类,并在输入内容时调用回调。回调是boost::function。如果我只有std::getline (std::cin, command);,则代码会运行,但如果添加行if(this->m_receiveHandler != NULL),则会因“访问冲突”而崩溃。我真的找不到正在发生的事情,所以我将问题减少到下面的测试。

问题不是完全确定的,有时我可以输入一两行,有时它会立即崩溃。程序输出的最后一件事总是“访问接收器处理程序”。

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) {};
}

您认为此代码有什么问题吗?

编辑:我正在使用Boost 1.49在Suse Linux上编译GCC 4.3.2。

1 个答案:

答案 0 :(得分:1)

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