tipos sintaxis programas funciones ejemplos declaracion datos comandos codigos c++ c++11 chrono

sintaxis - ¿Qué tipo usar para una variable de tiempo de espera en C++?



tipos de datos en c++ (2)

Cuando escribo una función en C ++ que toma un tiempo de espera como uno de sus argumentos, ¿qué tipo debo usar para el propio argumento de tiempo de espera?

Un ejemplo de tal función podría ser:

void my_function(bool work_really_hard, timeout_type timeout) { // Do stuff, until timeout is reached. }

He pensado en usar std::chrono::seconds para timeout_type , pero eso no permite usar ningún tiempo de espera en el reino sub-segundo.

Cuando se usa std::chrono::nanoseconds lugar, es complicado especificar, por ejemplo, 10 minutos.

¿Alguna forma de resolver esto de una manera razonable, manteniendo la firma de la función y las llamadas ordenadas y simples?


Cuando se usa std :: chrono :: nanosegundos en su lugar, es complicado especificar, por ejemplo, 10 minutos.

En realidad, no lo hace engorroso en lo más mínimo:

#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)); }

Salida:

600000000000

La única vez que tendrá problemas con los nanoseconds es si quiere pasar algo que no se convierta exactamente en nanoseconds , como picoseconds , o duration<long, ratio<1, 3>> (1/3 segundos unidades) .

Actualizar

Intenté que esta respuesta fuera información adicional para una respuesta ya aceptada que pensé que era una buena respuesta (por sehe). Se recomienda una solución con plantilla, que también considero bien.

Si desea aceptar cualquier std::chrono::duration , incluso una que deba truncar o redondear , ir con la respuesta eliminada de sehe es el camino a seguir:

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); }

Si por alguna razón no desea tratar con las plantillas y / o está contento con que sus clientes tengan que especificar solo las unidades que son exactamente convertibles a std::chrono:nanoseconds , entonces use std::chrono:nanoseconds como muestro Lo anterior también es completamente aceptable.

Todas las unidades "predefinidas" std::chrono :

hours minutes seconds milliseconds microseconds nanoseconds

son implícitamente convertibles a nanoseconds , y no implicarán ningún truncamiento o error de redondeo. El desbordamiento no ocurrirá mientras lo mantenga dentro de las dos líneas blancas brillantes (referencia oscura para mantener su automóvil en su propio carril). Mientras la duración sea de +/- 292 años, no tiene que preocuparse por el desbordamiento con estas unidades predefinidas.

Las funciones definidas std::this_thread::sleep_for como std::this_thread::sleep_for están programadas como se sugiere, por el motivo exacto de querer ser interoperables con cada chrono:duration imaginable (por ejemplo, 1/3 de un femtosegundo de punto flotante). Depende del diseñador de la API decidir si necesitan tanta flexibilidad en su propia API.

Si ahora he logrado confundirte en lugar de aclarar, no te preocupes demasiado. Si elige usar nanoseconds , las cosas funcionarán exactamente, sin truncamiento o error de redondeo, o el cliente obtendrá un error de tiempo de compilación. No habrá error de tiempo de ejecución.

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.

Y si el cliente recibe un error en tiempo de compilación, siempre puede usar duration_cast para solucionarlo:

my_function(true, duration_cast<nanoseconds>(picoseconds(100000.25))); // Ok

Para más detalles, consulte:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2661.htm

Dulce actualización del código original en la parte superior de esta respuesta. En C ++ 1y, que esperamos signifique C ++ 14:

using namespace std::literals; my_function(true, 10min); // also ok, is equal to 600000000000 nanoseconds

Pregunta: ¿Qué recomendaría usted como tiempo de espera de "infinito" (es decir, no se agote)?

Primero intentaría usar una API que no tuviera un tiempo de espera y que implique "no se agote". Por ejemplo condition_variable::wait . Si tuviera control sobre la API, crearía dicha firma sin un tiempo de espera.

De no ser así, crearía una serie de chrono::durations "grande" chrono::durations :

using days = std::chrono::duration < std::int32_t, std::ratio_multiply<std::chrono::hours::period, std::ratio<24>> >; using weeks = std::chrono::duration < std::int32_t, std::ratio_multiply<days::period, std::ratio<7>> >; using years = std::chrono::duration < std::int32_t, std::ratio_multiply<days::period, std::ratio<146097, 400>> >; using months = std::chrono::duration < std::int32_t, std::ratio_divide<years::period, std::ratio<12>> >;

Y luego usaría una de estas grandes duraciones en mi llamada, por ejemplo:

std::this_thread::sleep_for(years(3));

No intentaría empujar las cosas al máximo (podría romper los supuestos subyacentes que el sistema operativo ha hecho, por ejemplo). Simplemente elija arbitrariamente algo ridículamente grande (como 3 años). Eso llamará la atención de su revisor de código y probablemente iniciará una conversación informativa. :-)

Ahora disponible en video: https://www.youtube.com/watch?v=P32hvk8b13M :-)


Use un parámetro de plantilla para el tipo de tiempo de espera y espere uno de los tipos std::chrono , o algo con una interfaz similar; Esto te permitirá pasar en cualquier unidad de tiempo.

template<typename T> void wait_a_while(const T& duration) { std::this_thread::sleep(duration); } wait_a_while(boost::posix_time::seconds(5)); wait_a_while(std::chrono::milliseconds(30));