2012-09-24 10 views
9

Se voglio prendere più serrature senza correre il rischio di stallo, posso usare la funzione std::lock:Perché nessun supporto di timeout in std :: lock?

int data1, data2; 
std::mutex m1, m2; 
std::unique_lock<std::mutex> lock1(m1, std::defer_lock); 
std::unique_lock<std::mutex> lock2(m2, std::defer_lock); 

std::lock(lock1, lock2);   // guaranteed deadlock-free 

// work with data1 and data2 

Ma cosa succede se voglio acquistare le serrature entro un determinato periodo e il timeout altrimenti? C'è una ragione per cui non c'è nulla come try_until per i blocchi che è simile a wait_until per le variabili di condizione e di futuro?

+0

'std :: lock' non è un tipo, [è una funzione] (http://en.cppreference.com/w/cpp/thread/lock). :) – Xeo

+0

@Xeo: Giusto, grazie. Modificato. – KnowItAllWannabe

+0

@Nicol: Cosa c'è che non va con il passaggio dei blocchi differiti? 'std :: lock' accetta qualsiasi tipo di blocco e non dovrai preoccuparti di sbloccare in seguito. – Xeo

risposta

11

Perché nessun supporto di timeout in std :: lock?

  1. Perché nessuno lo ha proposto.

  2. Perché questa zona era così controversa che meno proposta, più è probabile che venga accettata.

  3. Perché avevamo paura che se standardizzassimo tutto, ci si annoiava.

  4. È stato lasciato come esercizio per il lettore.

Hmm ... Sono a corto di idee ... :-)

Oh!

E 'facile da fare per voi stessi se ne avete bisogno:

Aggiornamento

Ecco una riscrittura mi piace di più:

#include <mutex> 
#include <chrono> 

template <class Clock, class Duration, class L0, class L1> 
int 
try_lock_until(std::chrono::time_point<Clock, Duration> t, L0& l0, L1& l1) 
{ 
    std::unique_lock<L0> u0(l0, t); 
    if (u0.owns_lock()) 
    { 
     if (l1.try_lock_until(t)) 
     { 
      u0.release(); 
      return -1; 
     } 
     else 
      return 1; 
    } 
    return 0; 
} 

template <class Rep, class Period, class L0, class L1> 
int 
try_lock_for(std::chrono::duration<Rep, Period> d, L0& l0, L1& l1) 
{ 
    return try_lock_until(std::chrono::steady_clock::now() + d, l0, l1); 
} 


int main() 
{ 
    std::timed_mutex m1, m2; 
    try_lock_for(std::chrono::milliseconds(50), m1, m2); 
} 

Come suggerisce Anthony, sentitevi liberi di proporre Questo. Sentiti anche libero di usarlo e facci sapere se è stato effettivamente utile o no.

10

std::timed_mutex ha try_lock_until e try_lock_for funzioni membro. Tuttavia, hai ragione che non esiste un equivalente di std::lock con un timeout.

Il blocco di un mutex con un timeout è utile solo in particolari nicchie. Bloccare più mutex con un timeout non era qualcosa che qualcuno si sentisse abbastanza forte da proporre, quindi non è in C++ 11.

Il comitato standard sta attualmente cercando attivamente proposte per il prossimo standard. Se ritieni che un equivalente in timeout di std::lock sia prezioso, perché non scrivere una proposta?

Problemi correlati