无法从分离线程访问 C++ unordered_map 中的键值对

Cannot access key-value pair in a C++ unordered_map from a detached thread

我是一名 Java 开发人员,用 C++ 编写的内容才一周,所以请放轻松 :-)

我有一些代码可以分离一个线程,我需要使用该线程向已注册的服务器发送消息。该线程包含在具有 unordered_map 作为成员变量的单例 UpdateService 中。问题是我的键值对在添加到 unordered_map.

后丢失了

构造函数和单例实例化:

UpdateService& UpdateService::getInstance()
{
    static UpdateService onlyInstance;
    return onlyInstance;
}

UpdateService::UpdateService() 
{
    std::thread t(&UpdateService::pollForUpdates, this);
    t.detach();
}

轮询更新:

void UpdateService::pollForUpdates()
{
    while (true) {

        std::cout << "UpdateService 33 " << m_client_registrations.size() << "\n";

        std::unordered_map<std::string, ServerStub>::iterator iterator = m_client_registrations.begin();
        if ( iterator != m_client_registrations.end())
        {
            std::string clientId =  iterator->first;

            std::cout << "UpdateService 38 " << clientId << "\n";
            sendUpdate(clientId);
        }

        std::this_thread::sleep_for (std::chrono::seconds(1));

    }

}

我的 UpdateService 启用注册:

void UpdateService::registerForUpdates(std::string clientId, ServerStub server)
{

    if ( nullptr == getServer(clientId) ) {
        std::pair<std::string, ServerStub> pair (clientId, server);
        m_client_registrations.insert(pair);
        std::cout << "UpdateService 71 " << m_client_registrations.size() << "\n";
    }

    std::cout << "UpdateService 74 " << m_client_registrations.size() << "\n";
}

我通过这样的 Main 方法设置我的对象:

//initialise the update service and server stub
UpdateService service = UpdateService::getInstance();
ServerStub server = ServerStub();
service.registerForUpdates("clientId0", server);

控制台输出如下所示:

UpdateService 33 0
--> server is being registered here
UpdateService 71 1
UpdateService 74 1
UpdateService 33 0
UpdateService 33 0
UpdateService 33 0
UpdateService 33 0
UpdateService 33 0
UpdateService 33 0
UpdateService 33 0
UpdateService 33 0
UpdateService 33 0

任何人都可以向我建议这里可能发生的事情吗? map是一个成员变量,定义在我的头文件中 std::unordered_map m_client_registrations;

我也很想知道我应该如何调试它并自己解决它,我已经陷入深渊,周围没有 C++ 开发人员可以帮助我。我正在使用 Visual Studio Express 2012。

非常感谢!

您需要锁定以仲裁对地图的访问并随后同步其内存。向 UpdateService 添加一个 std::mutex 成员,并确保所有线程只有在其上持有锁时才能访问映射,如:

{
    std::lock_guard<std::mutex> lock(m_client_registrations_mutex);
    ...access or change the m_client_registrations...
} // automatic unlock happens as you leave scope