Если вы действительно нуждаетесь в подсекундной синхронизации, то любой вызов внешней команды, такой как date
или чтение внешнего системного файла, такого как /proc/uptime
или /proc/rct
, лишает цели точности до секунды.В обоих случаях требуется много ресурсов для извлечения запрошенной информации (т.е. времени)
Поскольку OP уже использует GNU awk, вы можете использовать динамическое расширение.Динамические расширения - это способ добавления новых функций в awk путем реализации новых функций, написанных на C или C ++, и динамической загрузки их с помощью gawk.Как написать эти функции, подробно описано в руководстве GNU awk .
К счастью, GNU awk 4.2.1 поставляется с набором динамических библиотек по умолчанию, которые можно загружать по желанию.Одна из этих библиотек - это библиотека time
с двумя простыми функциями:
the_time = gettimeofday()
Возвращает время в секундах, прошедшее с 1970-01-01 UTC, в видезначение с плавающей точкой.Если время недоступно для этой платформы, верните -1
и установите ERRNO
. Возвращаемое время должно быть с точностью до секунды , но фактическая точность может варьироваться в зависимости от платформы.Если на этой платформе доступен стандартный системный вызов C gettimeofday()
, он просто возвращает значение.В противном случае, если на MS-Windows, он пытается использовать GetSystemTimeAsFileTime()
.
result = sleep(seconds)
Попытка спать в течение seconds
секунд.Если seconds
отрицательно или попытка заснуть не удалась, верните -1
и установите ERRNO
.В противном случае верните ноль после сна в течение указанного количества времени.Обратите внимание, что секунды могут быть значениями с плавающей точкой (нецелыми).Детали реализации: в зависимости от доступности платформы, эта функция пытается использовать nanosleep()
или select()
для реализации задержки.
источник: GNU awk manual
Теперь можно вызывать эту функцию довольно простым способом:
awk '@load "time"; BEGIN{printf "%.6f", gettimeofday()}'
1553637193.575861
Чтобы продемонстрировать, что этот метод быстрее, чем более классические реализацииЯ рассчитал все 3 реализации, используя gettimeofday()
:
awk '@load "time"
function get_uptime( a) {
if((getline line < "/proc/uptime") > 0)
split(line,a," ")
close("/proc/uptime")
return a[1]
}
function curtime( cmd, line, time) {
cmd = "date \047+%Y/%m/%d %H:%M:%S.%N\047"
if ( (cmd | getline line) > 0 ) {
time = line
}
else {
print "Error: " cmd " failed" | "cat>&2"
}
close(cmd)
return time
}
BEGIN{
t1=getimeofday(); curtime(); t2=gettimeofday();
print "curtime()",t2-t1
t1=getimeofday(); get_uptime(); t2=gettimeofday();
print "get_uptime()",t2-t1
t1=getimeofday(); gettimeofday(); t2=gettimeofday();
print "gettimeofday()",t2-t1
}'
, который выдает:
curtime() 0.00519109
get_uptime() 7.98702e-05
gettimeofday() 9.53674e-07
Хотя очевидно, что curtime()
является самым медленным, поскольку он загружает внешний двоичный файл,довольно удивительно видеть, что awk невероятно быстр в обработке дополнительного внешнего файла / proc /.