我有一个网络应用程序,其中多个用户的userContext
保存在服务器中。用户不断向服务器发送不同的请求,服务器使用线程池和事件循环(例如epoll)异步处理这些请求。
所有用户都有自己的ID。此ID对于服务器是唯一的。服务器将用户上下文存储在map<int,userContext>
中。当服务器从one user
收到消息时,它将对消息进行解码。它还查找什么是request
和userID
等。然后服务器处理该请求,并更新(根据需要,在userContext current state
中更新状态机)存储在map
。
在我的应用程序中,有很多这样的过程调用(也很少嵌套),并且我通过value
传递用户上下文。我无法传递地图值的reference
。 (然后不再存在保护)。
下面是userContextStore
和两个过程的示例实现。
class userContext {
public:
int id;
int value1;
int value2;
userContext():id(-1),value1(-1),value2(-1){}
userContext(const userContext &context) {
this->id = context.id;
this->value1 = context.value1;
this->value2 = context.value2;
}
};
class contextStore {
public:
map<int,userContext> Map;
std::mutex m;
void update(userContext context,int id) {
lock_guard<std::mutex> lock(m);
if(Map.find(id) != Map.end()) {
Map[id] = context;
return;
}
Map[id] = context;
}
userContext getUserContext(int id) {
lock_guard<std::mutex> lock(m);
userContext context(Map[id]);
return context;
}
void printContext(int id) {
lock_guard<std::mutex> lock(m);
if(Map.find(id) != Map.end()) {
userContext temp(Map[id]);
cout << temp.value1 << endl;
cout << temp.value2 << endl;
}
}
};
void procedureA(contextStore &store,userContext context) {
// do some long processing using the provided context
// change context copy in between
// based on the above processing
context.value1 += 20; // example of a change
int id = context.id;
store.update(context,id);
}
void procedureB(contextStore &store,int id) {
userContext context(store.getUserContext(id));
// do some other long processing
// change context copy in between
context.value1 -= 10; // example of a change
store.update(context,id);
}
是否有更好的(可能是避免多次复制对象的方法)在特定过程调用内传递userContext
对象以进行所需的修改?
第二个问题是我正在使用胖锁来保护整个map
。在这种情况下,如果服务器中正在处理一个用户请求,则将不处理其他用户请求。 (因为锁保护了整个地图)。对于这种情况,是否有任何办法可以锁定细节?
谢谢!