python wait_for wait_在没有busywait的情况下在python中实现亚毫秒处理

我将如何使用linux下的python(在单核Raspberry Pi上运行)实现毫秒精度的数组处理.

我正在尝试解析MIDI文件中的信息,该文件已被预处理到一个数组,其中每毫秒我检查数组是否在当前时间戳处有条目并触发某些功能(如果有).

目前我正在使用time.time()并使用繁忙的等待(如here结束).这会占用所有CPU,因此我选择了更好的解决方案.

# iterate through all milliseconds

for current_ms in xrange(0,last+1):

start = time()

# check if events are to be processed

try:

events = allEvents[current_ms]

# iterate over all events for this millisecond

for event in events:

# check if event contains note information

if 'note' in event:

# check if mapping to pin exists

if event['note'] in mapping:

pin = mapping[event['note']]

# check if event contains on/off information

if 'mode' in event:

if event['mode'] == 0:

pin_off(pin)

elif event['mode'] == 1:

pin_on(pin)

else:

debug("unknown mode in event:"+event)

else:

debug("no mapping for note:" + event['note'])

except:

pass

end = time()

# fill the rest of the millisecond

while (end-start) < (1.0/(1000.0)):

end = time()

last是最后一个事件的毫秒(从预处理中得知)

由于too low accuracy of sleep(),我无法真正睡在“毫秒剩余”循环中.如果我要使用ctypes,我将如何正确地进行操作?

是否有一些Timer库可以每毫秒可靠地调用一次回调?

我目前的实现是在GitHub.使用这种方法我在drum_sample上得到大约4或5ms的偏差,总共3.7s(有模拟,因此没有附加真正的硬件).在30.7s样本上,偏差约为32ms(因此它至少不是线性的!).

import time

import timeit

import ctypes

libc = ctypes.CDLL('libc.so.6')

class Timespec(ctypes.Structure):

""" timespec struct for nanosleep,see:

http://linux.die.net/man/2/nanosleep """

_fields_ = [('tv_sec',ctypes.c_long),('tv_nsec',ctypes.c_long)]

libc.nanosleep.argtypes = [ctypes.POINTER(Timespec),ctypes.POINTER(Timespec)]

nanosleep_req = Timespec()

nanosleep_rem = Timespec()

def nsleep(us):

#print('nsleep: {0:.9f}'.format(us))

""" Delay microseconds with libc nanosleep() using ctypes. """

if (us >= 1000000):

sec = us/1000000

us %= 1000000

else: sec = 0

nanosleep_req.tv_sec = sec

nanosleep_req.tv_nsec = int(us * 1000)

libc.nanosleep(nanosleep_req,nanosleep_rem)

LOOPS = 10000

def do_sleep(min_sleep):

#print('try: {0:.9f}'.format(min_sleep))

total = 0.0

for i in xrange(0,LOOPS):

start = timeit.default_timer()

nsleep(min_sleep*1000*1000)

#time.sleep(min_sleep)

end = timeit.default_timer()

total += end - start

return (total / LOOPS)

iterations = 5

iteration = 1

min_sleep = 0.001

result = None

while True:

result = do_sleep(min_sleep)

#print('res: {0:.9f}'.format(result))

if result > 1.5 * min_sleep:

if iteration > iterations:

break

else:

min_sleep = result

iteration += 1

else:

min_sleep /= 2.0

print('FIN: {0:.9f}'.format(result))

我的i5的结果是

FIN: 0.000165443

而在RPi上它是

FIN: 0.000578617

这表明睡眠时间约为0.1或0.5毫秒,给定的抖动(倾向于睡得更久)最多可以帮助我减少负荷.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值