无法从分离线程访问 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
我是一名 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