Python解释器中的后台线程暂停时间.sleep()

时间:2013-08-23 01:06:36

标签: python multithreading python-multithreading

我们已经构建了一个自定义python解释器,并且正在尝试创建一个函数来启动后台线程,该后台线程定期调用函数来获取传感器读数,然后将该读取存储在循环缓冲区内(使用{{实现) 1}}最大长度。)

下面显示了我们实施的简化版本。我们面临的问题是,当我们从解释器调用deque开始后台线程时,后台线程中的代码似乎只执行一次(我们通过查看{{1的内容来确定) }})。此外,当我们尝试退出解释器(使用monitor_sensor())时,解释器会挂起并永不退出。

sensor_values

下面显示了解释器会话的转储,我们尝试运行后台线程并查看存储的数据 - 请注意,在尝试读取exit()中的值之间,我们等待的时间远远超过1秒睡眠

import code
import collections
import threading

def get_sensor_reading():
    return 5.0

sensor_values = {}

def monitor_sensor():
    sensor_values['sensor_1'] = collections.deque(maxlen=1000)
    background_thread = threading.Thread(target=run_monitor_sensor, args=[sensor_values, get_sensor_reading])
    background_thread.start()

def run_monitor_sensor(sensor_values, read_sensor_cmd):
    while True:
        reading = read_sensor_cmd()
        sensor_values['sensor_1'].append(reading)
        import time
        time.sleep(1)

imported_objects = {'monitor_sensor': monitor_sensor,
                    'sensor_values': sensor_values}

code.interact(local=imported_objects)

问题看起来是对sensor_values的调用 - 如果我们删除它,那么缓冲区将很快填满值。任何人都可以告诉我们为什么会出现这个问题,以及我们如何解决它?

更新

我们通过将218> python manage.py example Python 2.7.3 (default, Aug 1 2012, 05:16:07) [GCC 4.6.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>> monitor_sensor() >>> sensor_values {'sensor_1': deque([5.0], maxlen=1000)} >>> sensor_values {'sensor_1': deque([5.0], maxlen=1000)} 从循环内部移动到模块级别来解决问题。到目前为止没有任何线索为什么这解决了这个问题,但如果有人能够回答这个问题,那么就会接受这个答案。

1 个答案:

答案 0 :(得分:1)

您在没有锁定的情况下在两个线程之间共享一个可变值。

这实际上并不是保证在Python中是一个问题,它可能不是你的问题...但它肯定是错的,它可以导致像这样的问题

要修复它,请执行以下操作:

sensor_values = {}
sensor_lock = threading.Lock()

def monitor_sensor():
    sensor_values['sensor_1'] = collections.deque(maxlen=1000)
    background_thread = threading.Thread(target=run_monitor_sensor, args=[sensor_values, get_sensor_reading, sensor_lock])
    background_thread.start()

def run_monitor_sensor(sensor_values, read_sensor_cmd, sensor_lock):
    while True:
        reading = read_sensor_cmd()
        with sensor_lock:
            sensor_values['sensor_1'].append(reading)
        import time
        time.sleep(1)

def get_sensor_values():
    with sensor_lock:
        return sensor_values