I have a network application
F. It receives requests from one (or many) client network function.
F can handle multi-client requests using an
F maintains a state machine for each client(user).
F also maintains some context for each user or client. Whenever a message is received from a client network function (by one user),
F processes the message and if required fetch context specific to this user and updates the context.
Currently, the contexts of different users are maintained in a C++ STL map.
clientId is an integer and
context is a
struct containing user-specific data. Whenever I need to access the userMap I would take a lock first, access the data, and then unlock.
For example, if a client sends a request message
X. The server
epoll_wait() will get the event (i.e. the incoming message). Then this messages is read from the socket and processed further. In the server
handleX() method will be invoked (if user state and context is consistent and allows for
handleX to be executed for this user). Each of these
handleX function needs the current user context for some computation. it locks the userMap, gets or set the data, and then unlocks it.
In the single threaded version of
F, a single thread only waits for events and processes those events one by one.
I tried to use a thread pool to check the multicore scalability of
F. In this case, a single thread reads the messages from the socket and puts those messages in a queue. A pool of threads are waiting on the queue and picks any messages that pushed on the queue. But the throughput is not better than single-threaded code version of
I think locking is inherently serializing the
F's code. I would like to know is there any other model of user context store and retrieve to minimize lock contention?