python - Python中多线程调用的问题
问题描述
我有一个脚本,它有两个线程,一个运行这个目标函数的工作线程:
def worker_thread_function():
print(f'Worker thread started.')
while self._keep_running:
try:
task = worker_queue.get(timeout=5)
task() # I expect to be callables.
worker_queue.task_done() # See https://docs.python.org/3/library/queue.html
except queue.Empty:
continue
print(f'Worker thread finished.')
whereworker_queue
是一个全局对象,其他“管理线程”在其中放置必须完成的工作。另一个线程以这种方式定期将内容放入此队列中:
def other_thread_function():
while True:
time.sleep(1)
for device_name in devices_df.index: # Initialize this by logging once each device.
if has_to_be_logged(device_name):
print(f'Now queueing for log {device_name}')
worker_queue.put(lambda: log_single_device_standby_IV(device_name))
并且该功能log_single_device_standby_IV
使用该设备名称进行处理。我面临的问题是device_name
排队任务时值正确,但任务完成时值错误。log_single_device_standby_IV
如果我在这样的内部打印:
def log_single_device_standby_IV(device_name)
print(f'log_single_device_standby_IV({device_name})')
# do the stuff...
在我的输出中,我看到了这个:
Now queueing for log num5
log_single_device_standby_IV(num7) was called.
Now queueing for log num11
log_single_device_standby_IV(num7) was called.
Now queueing for log num5
log_single_device_standby_IV(num7) was called.
即它以某种方式改变了任何价值device_name
。num7
该设备num7
随便是中的最后一个devices_df.index
,不知道这是否可以提供任何提示。如果我像这样对设备名称进行硬编码:
def other_thread_function():
while True:
time.sleep(1)
for device_name in devices_df.index: # Initialize this by logging once each device.
if has_to_be_logged(device_name):
worker_queue.put(lambda: log_single_device_standby_IV('num4'))
它工作正常,即它num4
用作设备名称。
这里有什么问题?我不知道这是否与拥有多个线程、lambda 函数或什么有关...
解决方案
在问了这个问题并花了相当多的时间认为这是一个与线程相关的问题之后,我发现问题出在 lambda 函数上。使用 lambda 函数将行更改为
worker_queue.put(lambda dev=device_name: self.log_single_device_standby_IV(dev))
解决问题。
所以问题是 lambda 函数不是存储它的值device_name
而是对它的引用。
推荐阅读
- python - 是否有 Python 函数可以通过同时操作数组中的许多项来解决或支持?
- java - 制作一个 Spring Boot 应用程序以从现有的 oracle 数据库加载数据?
- api - '指定的值不能转换为 ReleaseStartMetadata 类型。使用 powershell 触发 VSTS 发布 API 时显示的消息
- javascript - 导入 google api 字体以响应“预加载”属性
- c# - 验证选择是一个范围
- odoo - 如何以在 Odoo 服务器上上传的格式下载文件?
- java - 如何使用 AWS lambda 授权 gmail API
- c# - 类型约束,类型存储在变量中
- php - 如何在没有 sql 查询的情况下获取唯一数据
- python - 使用正则表达式一次提取两个模式