¿Existe una forma simple de obtener una lista de todos los temporizadores actualmente en espera iniciados con erlang:send_after
, erlang:apply_after
, etc. en Erlang?Comprobar los temporizadores activos en Erlang
Respuesta
Para la depuración, puede usar dbg
:).
Primero cree una tabla de ets que almacenará todas las referencias del temporizador.
1> ets:new(timer_dbg, ['public', 'named_table', 'bag']).
timer_dbg
A continuación, cree una función de controlador dbg, que comprueba las llamadas que regresan de Erlang: send_after, y guarda la referencia temporizador vuelto a la mesa
2> Fun = fun({'trace', _Pid, 'return_from', {erlang, send_after, 3}, Ref}, []) ->
2> ets:insert(timer_dbg, {Ref}), [];
2> (_Msg, []) ->
2> []
2> end.
#Fun<erl_eval.12.113037538>
Ajuste la función como manejador de rastreo. También permite a juego en la llamada a erlang:send_after()
en todos los procesos
3> dbg:tracer('process', {Fun, []}).
{ok,<0.35.0>}
4> dbg:p('all', 'c').
{ok,[{matched,[email protected],26}]}
5> dbg:tpl(erlang, send_after, [{'_', [], [{'return_trace'}]}]).
{ok,[{matched,[email protected],1},{saved,1}]}
hacer algunas llamadas de prueba a erlang:send_after()
6> erlang:send_after(1000, self(), {}).
#Ref<0.0.0.43>
7> erlang:send_after(1000, self(), {}).
#Ref<0.0.0.47>
8> erlang:send_after(1000, self(), {}).
#Ref<0.0.0.51>
Finalmente compruebe que la tabla contiene las referencias:
9> ets:tab2list(timer_dbg).
[{#Ref<0.0.0.51>},{#Ref<0.0.0.43>},{#Ref<0.0.0.47>}]
esta manera almacenará todas las referencias de temporizador creadas por cualquier proceso que alguna vez haya llamado al erlang:send_after()
. Puede mapearlos en erlang:read_timer()
para filtrar los temporizadores activos.
Puede rastrear llamadas a send_after
de manera similar. También es posible hacer coincidir en cancel_timer
y eliminar manualmente las referencias canceladas de la tabla.
Además, si no tiene una aplicación con gran cantidad de mensajes, debería ser capaz de coincidir con los mensajes y/o funciones activadas por esos temporizadores, y eliminar las referencias expiradas de la lista.
podría ahorrarle las referencias que devuelve send_after, aply_after etc y el uso de Erlang: read_timer para comprobar si aún está esperando (read_timer devuelve false si el temporizador ha sido cancelado o no se esperaba más)
Eso no le dará a _all_ timers, pero solo a los que he guardado explícitamente. –
eso es una hack pero use: ets: tab2list (timer_tab). Durante dos temporizadores que posee:
ets:tab2list(timer_tab).
[{{1288384968923398,#Ref<0.0.0.30>},
timeout,
{erlang,integer_to_list,[23]}},
{{23334621698390115688,#Ref<0.0.0.189>},
timeout,
{erlang,integer_to_list,[23]}}]
Es útil solo para temporizadores de módulo 'timer' pero no para temporizadores creados con' erlang: send_after', 'erlang: apply_after' – hdima
true .. y te refieres a erlang: send_after solo supongo. ¿Hay algo como erlang: apply_after de alguna manera? – user425720
Oh, tienes razón, solo copio nombres de funciones de la pregunta original. – hdima
mirar el código en erl_bif_timer.c Creo volcado de bloqueo es el único lugar donde se puede encontrar una lista de todos los temporizadores BIF que eran simplemente activa. :-)
Bueno, lástima :) ¡Gracias! –
Me encuentro con la misma necesidad de rastrear temporizadores hoy.
Está en producción, por lo que no quiero usar dbg. Estos son erlang: temporizadores, por lo que mi solución anterior es inútil.
En su lugar analicé el parámetro nbif_timer de binary_to_list (erlang: system_info (info)).
Creo (aún no lo he confirmado), informa la memoria asignada para los temporizadores. En mi sistema x64 sería 17 palabras de 8 bytes = 136 bytes.
La monitorización de este valor muestra claramente cuándo el sistema establece una gran cantidad de temporizadores.
enjoy.
Lástima que no hay una forma directa, pero esto debería ser lo suficientemente útil para fines de prueba. (Planeo integrarlo en mis pruebas de propiedad). – eriksoe
- 1. Comprobar si el buzón está vacío en erlang
- 2. ¿Cómo configuramos los temporizadores en la aplicación WinRT?
- 3. Do C# ¿Los temporizadores transcurren en un hilo separado?
- 4. Temporizadores no reentrantes
- 5. Android NDK temporizadores
- 6. Temporizadores de cuenta atrás en jQuery
- 7. Retraso en un juego xna con temporizadores
- 8. ¿Se supone que los temporizadores EJB son persistentes/confiables?
- 9. ¿Los temporizadores .NET se ejecutan de forma asincrónica?
- 10. Temporizadores para medir la latencia
- 11. Erlang - C y Erlang
- 12. C# 5 y temporizadores asíncronos
- 13. Conflicto de Heroku entre los activos de gzip y los activos de precompilación
- 14. Tubería de rieles/activos: enumere dinámicamente los activos incluidos en un manifiesto
- 15. ¿Cómo cargar una imagen de los activos?
- 16. WebView no cargando los activos correctamente
- 17. Recargar .emacs para todos los búferes activos
- 18. Volcar stacktraces de todos los hilos activos
- 19. lectura del texto Unicode de los activos
- 20. cómo listar los reconocedores de gestos activos?
- 21. Poner el texto en los ejes no activos en MATLAB
- 22. Obtener una lista de correr Emacs temporizadores
- 23. ¿Cómo se implementa setTimeout en los intérpretes o temporizadores de javascript en general?
- 24. erlang incrustado en C
- 25. Nombrando nodos en Erlang
- 26. Recepción selectiva en Erlang
- 27. puntos image_tag a los activos/en Rails 3
- 28. ¿Cómo se enumeran los modos menores activos en emacs?
- 29. ¿Debo conservar los activos binarios en TFS? ¿Cómo?
- 30. Tiempo de caché de activos en los servidores de Shopify
Actualmente no hay 'erlang: apply_after' pero solo' timer: apply_after'. ¿Realmente quisiste decir 'erlang:' pero no 'timer:'? Porque los temporizadores creados con 'erlang: send_after' y' erlang: start_timer' son completamente diferentes y más livianos que los temporizadores creados con el módulo 'timer'. – hdima
Quiero decir 'erlang:' porque ya sabía cómo lidiar con los temporizadores creados por 'timer:' :) –
¿Por qué necesitarías esto? –