3

I was going to write a class which reads std::cin in a thread and calls a callback when something was entered. The callback is a boost::function. The code runs if I only have the std::getline (std::cin, command); , but crashes with "access violation" if I add the line if(this->m_receiveHandler != NULL). I really cannot find what's happening, so I reduced the problem down to the following test.

The problem is not fully deterministic, sometimes I can enter a line or two, sometimes it crashes immediately. The last thing the program outputs is always "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) {};
}

Do you see anything wrong with this code?

EDIT: I am compiling with GCC 4.3.2 on Suse Linux with Boost 1.49.

4

1 に答える 1

1

OSXのclangでこれを試したところ、うまくいきました(ただし、boostをstdに置き換えました)。別のパブリック メンバー関数でスレッドを開始するとどうなりますか? ブースト関数変数は、実際には 2 つのスレッド間の共有変数であり、おそらく何らかの同時実行プリミティブによって保護されている必要があります。スレッドは、実際には「this」オブジェクトの不完全なスナップショットを表示する場合があります。ただし、失敗する前に2回機能する理由は説明されていません。構築時に receiveHandler が何であるかが分かっていて、それを変更する必要がない場合は、boost::function をパラメーターとしてスレッドに渡すオプションがあります (コピーまたは移動でさえ可能です)。

于 2013-04-17T10:11:48.153 に答える