受保护的数据结构元素按值在函数之间传递

时间:2018-12-21 12:40:33

标签: c++ concurrency

我有一个网络应用程序,其中多个用户的userContext保存在服务器中。用户不断向服务器发送不同的请求,服务器使用线程池和事件循环(例如epoll)异步处理这些请求。

所有用户都有自己的ID。此ID对于服务器是唯一的。服务器将用户上下文存储在map<int,userContext>中。当服务器从one user收到消息时,它将对消息进行解码。它还查找什么是requestuserID等。然后服务器处理该请求,并更新(根据需要,在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。在这种情况下,如果服务器中正在处理一个用户请求,则将不处理其他用户请求。 (因为锁保护了整个地图)。对于这种情况,是否有任何办法可以锁定细节?

谢谢!

0 个答案:

没有答案