std::lock - cppreference.com
De cppreference.com
| Definido en el archivo de encabezado |
||
|
|
(desde C++11) | |
Bloquea los objetos Lockable dados lock1, lock2, ..., lockn usando un algoritmo de evitación de bloqueo mutuo para evitar el bloqueo mutuo.
Los objetos se bloquean por una serie de llamadas no especificadas a lock, try_lock, y unlock. Si una llamada a lock o unlock resulta en una excepción, se llama a unlock por cualquiera de los objetos bloqueados antes de volver a lanzar.
Parámetros
| lock1, lock2, ... , lockn | - | Los objetos Lockable a bloquear. |
Valor de retorno
(none)
Notas
Boost proporciona una versión de esta función que toma una secuencia de objetos Lockable definidos por un par de iteradores.
std::scoped_lock ofrece un envoltorio RAII para esta función, y se prefiere generalmente a una llamada manifiesta a std::lock.
Ejemplo
El siguiente ejemplo utiliza a std::lock para bloquear pares de mutexes sin bloqueo mutuo.
#include <mutex> #include <thread> #include <iostream> #include <vector> #include <functional> #include <chrono> #include <string> struct Employee { Employee(std::string id) : id(id) {} std::string id; std::vector<std::string> lunch_partners; std::mutex m; std::string output() const { std::string ret = "Empleado(a) " + id + " tiene compañeros para el almuerzo: "; for( const auto& partner : lunch_partners ) ret += partner + " "; return ret; } }; void send_mail(Employee &, Employee &) { // simular una operación de mensajeo de largo tiempo std::this_thread::sleep_for(std::chrono::seconds(1)); } void assign_lunch_partner(Employee &e1, Employee &e2) { static std::mutex io_mutex; { std::lock_guard<std::mutex> lk(io_mutex); std::cout << e1.id << " and " << e2.id << " están a la espera de cerrojos" << std::endl; } // usar std::lock para adquirir dos cerrojos sin preocuparse de // otras llamadas a assign_lunch_partner que nos bloqueen mutuamente { std::lock(e1.m, e2.m); std::lock_guard<std::mutex> lk1(e1.m, std::adopt_lock); std::lock_guard<std::mutex> lk2(e2.m, std::adopt_lock); // Código equivalente code (si se necesitan unique_locks, es decir, para variables de condición) // std::unique_lock<std::mutex> lk1(e1.m, std::defer_lock); // std::unique_lock<std::mutex> lk2(e2.m, std::defer_lock); // std::lock(lk1, lk2); // Solución superior disponible en C++17 // std::scoped_lock lk(e1.m, e2.m); { std::lock_guard<std::mutex> lk(io_mutex); std::cout << e1.id << " y " << e2.id << " obtuvieron cerrojos" << std::endl; } e1.lunch_partners.push_back(e2.id); e2.lunch_partners.push_back(e1.id); } send_mail(e1, e2); send_mail(e2, e1); } int main() { Employee ana("Ana"), beto("Beto"), cristina("Cristina"), david("David"); // asignar en hilos paralelos ya que enviar correo a usuarios sobre // las asignaciones de los compañeros de almuerzo toma mucho tiempo std::vector<std::thread> threads; threads.emplace_back(assign_lunch_partner, std::ref(Ana), std::ref(Beto)); threads.emplace_back(assign_lunch_partner, std::ref(Cristina), std::ref(Beto)); threads.emplace_back(assign_lunch_partner, std::ref(Cristina), std::ref(Ana)); threads.emplace_back(assign_lunch_partner, std::ref(David), std::ref(Beto)); for (auto &thread : threads) thread.join(); std::cout << ana.output() << '\n' << beto.output() << '\n' << cristina.output() << '\n' << david.output() << '\n'; }
Posible salida:
Ana y Beto están a la espera de cerrojos Ana y Beto obtuvieron cerrojos Cristina y Beto están a la espera de cerrojos Cristina y Beto obtuvieron cerrojos Cristina y Ana están a la espera de cerrojos Cristina y Ana obtuvieron cerrojos David y Beto están a la espera de cerrojos David y Beto obtuvieron cerrojos Empleado(a) Ana tiene compañeros para el almuerzo: Beto Cristina Empleado(a) Beto tiene compañeros para el almuerzo: Ana Cristina David Empleado(a) Cristina tiene compañeros para el almuerzo: Beto Ana Empleado(a) David tiene compañeros para el almuerzo: Beto
Véase también
Intenta tomar posesión de los mutex mediante llamadas repetidas a try_lock. (plantilla de función) [editar] | |
| Envoltorio RAII que evita bloqueo mutuo para múltiples mutex. (plantilla de clase) [editar] |