How to get millisecond and microsecond-resolution timestamps in Python
我终于明白了这一点,我想分享这些知识,节省一些时间,所以请看下面我的答案。但是,我仍然需要Linux的答案,因此如果您知道,请回答,因为我答案中的代码仅适用于Windows。
更新:我也已经为Linux解决了这个问题,包括针对Python3.3之前的版本(例如:针对Raspberry PI),我已经在下面的答案中发布了我的新模块/代码。
我最初的问题是:如何在Python中获得毫秒和微秒分辨率的时间戳?我还想要类似于arduino的delay和delayMicroseconds()函数。
更新日期:2018年12月19日:请不要将此问题标记为副本,并在肯定没有答案的情况下说它在其他地方有答案。这个问题几个月前被标记为这个问题的副本。请参见这里:
它说,"这个问题已经有答案了。"不幸的是,这不是真的。几年前,我在问这个问题之前读了这些答案,但他们没有回答我的问题,也没有满足我的需要。它们同样不适用于我的问题,就像这里最被否决的答案一样,因为不幸的是,它是错误的,因为它依赖于
请重新打开我的问题。它不是复制品。它没有其他问题的事先答案。已包含答案的链接问题依赖于
谢谢你抽出时间。:)
对于Windows:这里是一个针对两个Linux(也适用于python 3.3之前版本)和Windows的完全功能模块:
函数和代码示例。功能包括:
- 微()
- 毫秒()
- 删除()
- 延迟微秒()
python代码模块:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | """ GS_timing.py -create some low-level Arduino-like millis() (milliseconds) and micros() (microseconds) timing functions for Python By Gabriel Staples http://www.ElectricRCAircraftGuy.com -click"Contact me" at the top of my website to find my email address Started: 11 July 2016 Updated: 13 Aug 2016 History (newest on top): 20160813 - v0.2.0 created - added Linux compatibility, using ctypes, so that it's compatible with pre-Python 3.3 (for Python 3.3 or later just use the built-in time functions for Linux, shown here: https://docs.python.org/3/library/time.html) -ex: time.clock_gettime(time.CLOCK_MONOTONIC_RAW) 20160711 - v0.1.0 created - functions work for Windows *only* (via the QPC timer) References: WINDOWS: -personal (C++ code): GS_PCArduino.h 1) Acquiring high-resolution time stamps (Windows) -https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx 2) QueryPerformanceCounter function (Windows) -https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx 3) QueryPerformanceFrequency function (Windows) -https://msdn.microsoft.com/en-us/library/windows/desktop/ms644905(v=vs.85).aspx 4) LARGE_INTEGER union (Windows) -https://msdn.microsoft.com/en-us/library/windows/desktop/aa383713(v=vs.85).aspx -*****https://stackoverflow.com/questions/4430227/python-on-win32-how-to-get- absolute-timing-cpu-cycle-count LINUX: -https://stackoverflow.com/questions/1205722/how-do-i-get-monotonic-time-durations-in-python """ import ctypes, os #Constants: VERSION = '0.2.0' #------------------------------------------------------------------- #FUNCTIONS: #------------------------------------------------------------------- #OS-specific low-level timing functions: if (os.name=='nt'): #for Windows: def micros(): "return a timestamp in microseconds (us)" tics = ctypes.c_int64() freq = ctypes.c_int64() #get ticks on the internal ~2MHz QPC clock ctypes.windll.Kernel32.QueryPerformanceCounter(ctypes.byref(tics)) #get the actual freq. of the internal ~2MHz QPC clock ctypes.windll.Kernel32.QueryPerformanceFrequency(ctypes.byref(freq)) t_us = tics.value*1e6/freq.value return t_us def millis(): "return a timestamp in milliseconds (ms)" tics = ctypes.c_int64() freq = ctypes.c_int64() #get ticks on the internal ~2MHz QPC clock ctypes.windll.Kernel32.QueryPerformanceCounter(ctypes.byref(tics)) #get the actual freq. of the internal ~2MHz QPC clock ctypes.windll.Kernel32.QueryPerformanceFrequency(ctypes.byref(freq)) t_ms = tics.value*1e3/freq.value return t_ms elif (os.name=='posix'): #for Linux: #Constants: CLOCK_MONOTONIC_RAW = 4 # see <linux/time.h> here: https://github.com/torvalds/linux/blob/master/include/uapi/linux/time.h #prepare ctype timespec structure of {long, long} class timespec(ctypes.Structure): _fields_ =\ [ ('tv_sec', ctypes.c_long), ('tv_nsec', ctypes.c_long) ] #Configure Python access to the clock_gettime C library, via ctypes: #Documentation: #-ctypes.CDLL: https://docs.python.org/3.2/library/ctypes.html #-librt.so.1 with clock_gettime: https://docs.oracle.com/cd/E36784_01/html/E36873/librt-3lib.html #- #-Linux clock_gettime(): http://linux.die.net/man/3/clock_gettime librt = ctypes.CDLL('librt.so.1', use_errno=True) clock_gettime = librt.clock_gettime #specify input arguments and types to the C clock_gettime() function # (int clock_ID, timespec* t) clock_gettime.argtypes = [ctypes.c_int, ctypes.POINTER(timespec)] def monotonic_time(): "return a timestamp in seconds (sec)" t = timespec() #(Note that clock_gettime() returns 0 for success, or -1 for failure, in # which case errno is set appropriately) #-see here: http://linux.die.net/man/3/clock_gettime if clock_gettime(CLOCK_MONOTONIC_RAW , ctypes.pointer(t)) != 0: #if clock_gettime() returns an error errno_ = ctypes.get_errno() raise OSError(errno_, os.strerror(errno_)) return t.tv_sec + t.tv_nsec*1e-9 #sec def micros(): "return a timestamp in microseconds (us)" return monotonic_time()*1e6 #us def millis(): "return a timestamp in milliseconds (ms)" return monotonic_time()*1e3 #ms #Other timing functions: def delay(delay_ms): "delay for delay_ms milliseconds (ms)" t_start = millis() while (millis() - t_start < delay_ms): pass #do nothing return def delayMicroseconds(delay_us): "delay for delay_us microseconds (us)" t_start = micros() while (micros() - t_start < delay_us): pass #do nothing return #------------------------------------------------------------------- #EXAMPLES: #------------------------------------------------------------------- #Only executute this block of code if running this module directly, #*not* if importing it #-see here: http://effbot.org/pyfaq/tutor-what-is-if-name-main-for.htm if __name__ =="__main__": #if running this module as a stand-alone program #print loop execution time 100 times, using micros() tStart = micros() #us for x in range(0, 100): tNow = micros() #us dt = tNow - tStart #us; delta time tStart = tNow #us; update print("dt(us) =" + str(dt)) #print loop execution time 100 times, using millis() print(" ") tStart = millis() #ms for x in range(0, 100): tNow = millis() #ms dt = tNow - tStart #ms; delta time tStart = tNow #ms; update print("dt(ms) =" + str(dt)) #print a counter once per second, for 5 seconds, using delay print(" start") for i in range(1,6): delay(1000) print(i) #print a counter once per second, for 5 seconds, using delayMicroseconds print(" start") for i in range(1,6): delayMicroseconds(1000000) print(i) |
如果您知道如何在Linux中获得上述毫秒和微秒分辨率时间戳,请发布,因为这也将非常有用。
这也适用于Linux,包括Python3.3之前的版本,因为我通过ctypes模块使用C函数来读取时间戳。
(注:以上代码最初发布在这里:http://www.electrircaircraftguy.com/2016/07/arduino-like-millisecond-and-microsecond-timestamps-in-python.html)
特别感谢@arminronacher为他出色的python 3.3之前的linux提供的答案:https://stackoverflow.com/a/1205762/4561877
更新:在python3.3之前,内置的python时间库(https://docs.python.org/3.5/library/time.html)没有任何显式的高分辨率函数。不过,现在它提供了其他选项,包括一些高分辨率功能。
不过,上面的模块为python3.3之前和之后的python代码提供了高分辨率的时间戳,在Linux和Windows上都是如此。
这是我的意思的一个例子,表明
代码演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | import time import GS_timing as timing def delayMicroseconds(n): time.sleep(n / 1000000.) def delayMillisecond(n): time.sleep(n / 1000.) t_start = 0 t_end = 0 #using time.sleep print('using time.sleep') print('delayMicroseconds(1)') for x in range(10): t_start = timing.micros() #us delayMicroseconds(1) t_end = timing.micros() #us print('dt (us) = ' + str(t_end - t_start)) print('delayMicroseconds(2000)') for x in range(10): t_start = timing.micros() #us delayMicroseconds(2000) t_end = timing.micros() #us print('dt (us) = ' + str(t_end - t_start)) #using GS_timing print(' using GS_timing') print('timing.delayMicroseconds(1)') for x in range(10): t_start = timing.micros() #us timing.delayMicroseconds(1) t_end = timing.micros() #us print('dt (us) = ' + str(t_end - t_start)) print('timing.delayMicroseconds(2000)') for x in range(10): t_start = timing.micros() #us timing.delayMicroseconds(2000) t_end = timing.micros() #us print('dt (us) = ' + str(t_end - t_start)) |
我的Windows 8.1计算机上的示例结果(请注意,time.sleep的情况更糟):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | using time.sleep delayMicroseconds(1) dt (us) = 2872.059814453125 dt (us) = 886.3939208984375 dt (us) = 770.4649658203125 dt (us) = 1138.7698974609375 dt (us) = 1426.027099609375 dt (us) = 734.557861328125 dt (us) = 10617.233642578125 dt (us) = 9594.90576171875 dt (us) = 9155.299560546875 dt (us) = 9520.526611328125 delayMicroseconds(2000) dt (us) = 8799.3056640625 dt (us) = 9609.2685546875 dt (us) = 9679.5439453125 dt (us) = 9248.145263671875 dt (us) = 9389.721923828125 dt (us) = 9637.994262695312 dt (us) = 9616.450073242188 dt (us) = 9592.853881835938 dt (us) = 9465.639892578125 dt (us) = 7650.276611328125 using GS_timing timing.delayMicroseconds(1) dt (us) = 53.3477783203125 dt (us) = 36.93310546875 dt (us) = 36.9329833984375 dt (us) = 34.8812255859375 dt (us) = 35.3941650390625 dt (us) = 40.010986328125 dt (us) = 38.4720458984375 dt (us) = 56.425537109375 dt (us) = 35.9072265625 dt (us) = 36.420166015625 timing.delayMicroseconds(2000) dt (us) = 2039.526611328125 dt (us) = 2046.195068359375 dt (us) = 2033.8841552734375 dt (us) = 2037.4747314453125 dt (us) = 2032.34521484375 dt (us) = 2086.2059326171875 dt (us) = 2035.4229736328125 dt (us) = 2051.32470703125 dt (us) = 2040.03955078125 dt (us) = 2027.215576171875 |
我的Raspberry PI版本1b+上的示例结果(注意,在使用time.sleep和我的模块之间的结果基本相同……显然,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | using time.sleep delayMicroseconds(1) dt (us) = 1022.0 dt (us) = 417.0 dt (us) = 407.0 dt (us) = 450.0 dt (us) = 2078.0 dt (us) = 393.0 dt (us) = 1297.0 dt (us) = 878.0 dt (us) = 1135.0 dt (us) = 2896.0 delayMicroseconds(2000) dt (us) = 2746.0 dt (us) = 2568.0 dt (us) = 2512.0 dt (us) = 2423.0 dt (us) = 2454.0 dt (us) = 2608.0 dt (us) = 2518.0 dt (us) = 2569.0 dt (us) = 2548.0 dt (us) = 2496.0 using GS_timing timing.delayMicroseconds(1) dt (us) = 572.0 dt (us) = 673.0 dt (us) = 1084.0 dt (us) = 561.0 dt (us) = 728.0 dt (us) = 576.0 dt (us) = 556.0 dt (us) = 584.0 dt (us) = 576.0 dt (us) = 578.0 timing.delayMicroseconds(2000) dt (us) = 2741.0 dt (us) = 2466.0 dt (us) = 2522.0 dt (us) = 2810.0 dt (us) = 2589.0 dt (us) = 2681.0 dt (us) = 2546.0 dt (us) = 3090.0 dt (us) = 2600.0 dt (us) = 2400.0 |
1 2 3 4 5 6 7 | import time def delayMicroseconds(n): time.sleep(n / 1000000.) def delayMillisecond(n): time.sleep(n / 1000.) |
另请参见:如何在python中进行时间延迟?