Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python解释器中的后台线程按时挂起。sleep()_Python_Multithreading_Python Multithreading - Fatal编程技术网

Python解释器中的后台线程按时挂起。sleep()

Python解释器中的后台线程按时挂起。sleep(),python,multithreading,python-multithreading,Python,Multithreading,Python Multithreading,我们已经构建了一个定制的python解释器,并且正在尝试创建一个函数来启动一个后台线程,该线程定期调用一个函数来获取传感器读数,然后将该读数存储在一个循环缓冲区中(使用最大长度的deque实现) 下面显示了我们实现的简化版本。我们面临的问题是,当我们从解释器调用monitor\u sensor()。此外,当我们尝试退出解释器时(使用exit()),解释器将挂起并且永远不会退出 import code import collections import threading def get_sen

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

下面显示了我们实现的简化版本。我们面临的问题是,当我们从解释器调用
monitor\u sensor()。此外,当我们尝试退出解释器时(使用
exit()
),解释器将挂起并且永远不会退出

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)
下面显示了解释器会话的转储,其中我们尝试运行后台线程并查看存储的数据-请注意,在尝试读取
传感器\u值中的值时,我们等待的时间远远超过了1秒睡眠时间

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)}
问题似乎在于调用
time.sleep(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

这不是你的问题,但是……为什么你会在代码中间输入代码>导入时间<代码>?总之,原因<代码>退出<代码>挂起就是程序不会终止直到所有(非守护进程)线程执行,并且<代码>退出<代码>只终止主线程。您必须停止(或后台监控)后台线程。此外,如果您想知道后台循环运行了多少次,而不是试图猜测,为什么不让它执行类似于
sys.stderr.write('.');sys.stderr.flush()?如果它暂停,很难错过。回复第一条评论:当我们第一次把它放在一起,并在模块级别导入时间时,从循环内部调用time.sleep()似乎出现了一个问题(错误报告为“找不到时间”或类似的问题)。这是一个遗留问题,将查看是否可以删除循环中的导入。回复第二条评论:很高兴知道,谢谢-我们实际上通过使用
线程解决了这个问题。启动新线程
,而不是创建和启动
线程。线程
。谢谢-耶,我们认为这不是线程安全的(这只是初稿)但这似乎不是问题的根源。非常感谢您保存的锁定指南,我们已经应用了升级!