Digamos que tengo un programa multiproceso de C++ que maneja las solicitudes en forma de una llamada de función al handleRequest(string key)
. Cada llamada a handleRequest
se produce en una secuencia separada, y hay una cantidad arbitrariamente grande de valores posibles para key
.¿Cómo uso una cadena arbitraria como un candado en C++?
Quiero el siguiente comportamiento:
- llamadas simultáneas a
handleRequest(key)
son serializado cuando tienen el mismo valor parakey
. - La serialización global está minimizada.
El cuerpo de handleRequest
podría tener este aspecto:
void handleRequest(string key) {
KeyLock lock(key);
// Handle the request.
}
Pregunta: ¿Cómo meKeyLock
aplicar para conseguir el comportamiento requerido?
Una implementación ingenua podría empezar así:
KeyLock::KeyLock(string key) {
global_lock->Lock();
internal_lock_ = global_key_map[key];
if (internal_lock_ == NULL) {
internal_lock_ = new Lock();
global_key_map[key] = internal_lock_;
}
global_lock->Unlock();
internal_lock_->Lock();
}
KeyLock::~KeyLock() {
internal_lock_->Unlock();
// Remove internal_lock_ from global_key_map iff no other threads are waiting for it.
}
... pero eso requiere un bloqueo global al principio y al final de cada solicitud, así como la creación de un Lock
objeto separado para cada solicitud. Si la contención es alta entre llamadas al handleRequest
, eso podría no ser un problema, pero podría imponer una gran sobrecarga si la contención es baja.
Normalmente solo se pueden crear tantos Mutexes con nombre. En Linux, al menos, puedes cambiar la cantidad que obtienes, pero me gustaría tener cuidado con el uso de este método con algo para juntar los viejos Mutexes. –