Ruby中有一个比sleep
更好的方法来实现精细/高分辨率延迟吗?
我想在纯ruby中实现DHT11传感器协议,并且我无法使用原生sleep
方法获得一致的延迟。
有问题的延迟高达20毫秒,直到40微秒。
为了测试这些延迟,我正在运行一个简单的增量时间计算,如下所示:
irb(main):043:0> # 20ms delays are fine
irb(main):044:0* 5.times do
irb(main):045:1* t1 = Time.now.to_f
irb(main):046:1> sleep 0.02
irb(main):047:1> t2 = Time.now.to_f
irb(main):048:1> puts t2 - t1
irb(main):049:1> end
0.02004218101501465
0.021020889282226562
0.020302772521972656
0.020184040069580078
0.020570993423461914
irb(main):050:0> # 40us delays are inconsistant and/or broken
irb(main):051:0* 5.times do
irb(main):052:1* t1 = Time.now.to_f
irb(main):053:1> sleep 0.00004
irb(main):054:1> t2 = Time.now.to_f
irb(main):055:1> puts t2 - t1
irb(main):056:1> end
0.0
0.0
0.0005059242248535156
0.0
0.0
这个依赖于微秒延迟的协议是否可以在Ruby中实现?
正在测试的构建版本为ruby 2.3.1p112 (2016-04-26 revision 54768) [i386-mingw32]
,并且正在Windows 10
上运行。虽然在开发板上的ruby 2.3.1p112 (2016-04-26) [arm-linux-gnueabihf]
上使用Linux orangepizero 4.13.16-sunxi #20 SMP Fri Nov 24 19:50:07 CET 2017 armv7l armv7l armv7l GNU/Linux
的H2 CPU上运行相同的测试时,我将使用传感器,我得到更精细的分辨率结果,但结果仍然不一致:
irb(main):001:0> # 20ms delays are fine
irb(main):002:0* 5.times do
irb(main):003:1* t1 = Time.now.to_f
irb(main):004:1> sleep 0.02
irb(main):005:1> t2 = Time.now.to_f
irb(main):006:1> puts t2 - t1
irb(main):007:1> end
0.020125150680541992
0.020093679428100586
0.020082950592041016
0.020090341567993164
0.020081043243408203
irb(main):008:0> # 40us delays are inconsistant and/or broken
irb(main):009:0* 5.times do
irb(main):010:1* t1 = Time.now.to_f
irb(main):011:1> sleep 0.00004
irb(main):012:1> t2 = Time.now.to_f
irb(main):013:1> puts t2 - t1
irb(main):014:1> end
0.0003037452697753906
0.00022101402282714844
0.00022673606872558594
0.0002200603485107422
0.00021409988403320312
这是否可能或者我是否希望编写或使用其他C语言实现,然后从Ruby调用它?