Quando si utilizza std :: :: crono nanosecondi, invece, è ingombrante per specificare, ad esempio, 10 minuti.
In realtà, non lo rende ingombrante minimamente:
#include <chrono>
#include <iostream>
void my_function(bool work_really_hard, std::chrono::nanoseconds timeout)
{
std::cout << timeout.count() << '\n';
}
int
main()
{
my_function(true, std::chrono::minutes(10));
}
uscita:
600000000000
L'unica volta che avrai problemi con nanoseconds
è se si vuole passare qualcosa che non si convertirà esattamente in nanoseconds
, ad esempio picoseconds
o duration<long, ratio<1, 3>>
(unità di 1/3 di secondo).
Aggiornamento
ho inteso questa risposta per essere ulteriori informazioni per una risposta già accettato che ho pensato è stata una buona risposta (da sehe). sehe ha raccomandato una soluzione basata su modelli, che considero anche valida.
Se si desidera accettare qualsiasistd::chrono::duration
, anche uno che potrebbe essere necessario truncate or round, poi andando con la risposta cancellato di sehe è la strada da percorrere:
template <typename Rep, typename Period>
void my_function(bool work_really_hard, std::chrono::duration<Rep, Period> timeout)
{
// Do stuff, until timeout is reached.
std::this_thread::sleep_for(timeout);
}
Se per qualche motivo non si vuole trattare con modelli e/o si è soddisfatti di avere i clienti che devono specificare solo unità che sono esattamente convertibili in std::chrono:nanoseconds
, quindi utilizzare std::chrono:nanoseconds
come mostrato sopra è anche completamente accettabile.
Tutte le std::chrono
unità "predefinite":
hours
minutes
seconds
milliseconds
microseconds
nanoseconds
sono implicitamente convertibile in nanoseconds
, e non comporterà alcun troncamento o errore inerente. Il trabocco non si verificherà fintanto che lo si mantiene entro le due linee bianche luminose (riferimento oscuro per mantenere l'auto nella propria corsia).Finché la durata è entro +/- 292 anni, non devi preoccuparti di un eccesso con queste unità predefinite.
Le funzioni std-defined come std::this_thread::sleep_for
sono rappresentate come se stesse suggerendo esattamente il motivo per cui si desidera essere interoperabili con ogni chrono:duration
immaginabile (ad esempio 1/3 di un femtosecondo a virgola mobile). Spetta al progettista dell'API decidere se hanno bisogno di molta flessibilità nella propria API.
Se ora sono riuscito a confonderti invece di chiarire, non ti preoccupare troppo. Se si sceglie di utilizzare nanoseconds
, le cose funzioneranno esattamente, senza errori di troncamento o di arrotondamento, oppure il client riceverà un errore in fase di compilazione. Ci sarà no errore di runtime.
void my_function(bool work_really_hard, std::chrono::nanoseconds timeout)
{
std::cout << timeout.count() << '\n';
}
int
main()
{
using namespace std;
using namespace std::chrono;
typedef duration<double, pico> picoseconds;
my_function(true, picoseconds(100000.25));
}
test.cpp:15:9: error: no matching function for call to 'my_function'
my_function(true, picoseconds(100000.25));
^~~~~~~~~~~
test.cpp:4:10: note: candidate function not viable: no known conversion from 'duration<double, ratio<[...], 1000000000000>>' to
'duration<long long, ratio<[...], 1000000000>>' for 2nd argument
void my_function(bool work_really_hard, std::chrono::nanoseconds timeout)
^
1 error generated.
E se il cliente ottiene un errore di compilazione, si può sempre usare duration_cast
per lavorare intorno ad esso:
my_function(true, duration_cast<nanoseconds>(picoseconds(100000.25))); // Ok
Per ulteriori dettagli, vedere:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2661.htm
Aggiornamento dolce al codice originale nella parte superiore di questa risposta. In C++ 1A, che speriamo significa C++ 14:
using namespace std::literals;
my_function(true, 10min); // also ok, is equal to 600000000000 nanoseconds
Domanda: Cosa consiglia come un timeout di "infinito" (cioè non TIME OUT)
I prima tenterebbe di utilizzare un'API che non ha richiesto un timeout e che implicava "non timeout". Ad esempio condition_variable::wait
. Se avessi il controllo dell'API, creerei tale firma senza un timeout.
In mancanza di questo, vorrei creare una serie di "grande" chrono::durations
:
typedef std::chrono::duration
<
std::int32_t, std::ratio_multiply<std::chrono::hours::period, std::ratio<24>>
> days;
typedef std::chrono::duration
<
std::int32_t, std::ratio_multiply<days::period, std::ratio<7>>
> weeks;
typedef std::chrono::duration
<
std::int32_t, std::ratio_multiply<days::period, std::ratio<146097, 400>>
> years;
typedef std::chrono::duration
<
std::int32_t, std::ratio_divide<years::period, std::ratio<12>>
> months;
E poi vorrei usare uno di questi grandi durate nella mia chiamata, ad esempio:
std::this_thread::sleep_for(years(3));
I non proverei a push_things al massimo (potresti rompere le ipotesi sottostanti che il sistema operativo ha fatto per esempio). Scegli arbitrariamente qualcosa di ridicolmente grande (come 3 anni). Ciò attirerà l'attenzione del tuo revisore del codice e probabilmente darà inizio a una conversazione informativa. :-)
Ora disponibile in video: https://www.youtube.com/watch?v=P32hvk8b13M :-)
utilizzare il '' wait_until' o primitive sleep_until'? IOW, usa una scadenza invece di un timeout – sehe
@sehe Gli interni di come il timeout è rispettato non sono rilevanti per questa domanda (non ho alcun controllo su di essi). Sono solo preoccupato di quale tipo utilizzare per il timeout nella firma della funzione. – JohnCand
Come su millisecondi? È _kinda_ standard per specificare i timeout in millisecondi. Inoltre, i tipi 'std :: chrono' sono espressi in rapporti, quindi puoi usare valori non interi. – Tibor