使用 Python 3 在后台线程中加载数据
Load data in background thread with Python 3
无法解决这个看似简单的问题,我有点沮丧:
我有一个函数需要一些时间来加载数据:
def import_data(id):
time.sleep(5)
return 'data' + str(id)
一个DataModel
class调用这个函数,管理两个数据集。
class DataModel():
def __init__(self):
self._data_1 = import_data(1)
self._data_2 = import_data(2)
def retrieve_data_1(self):
return self._data_1
def retrieve_data_2(self):
return self._data_2
现在,主要 UI 创建 DataModel
,调用两个 import_data
函数,这会阻止它。
def main_ui():
# This takes 5 seconds for each dataset and blocks the main UI thread
dm = DataModel()
# Other stuff is happening. This time could be used to load data in the background
time.sleep(2)
# Retrieve the first dataset
data_1 = dm.retrieve_data_1()
# User interaction. This time could be used to load even larger datasets
time.sleep(10)
# Retrieve the second dataset
data_2 = dm.retrieve_data_2()
我希望在后台加载数据集以减少 UI 被阻止的时间。
我的想法是像这样实现它 pseudocode:
class DataModel():
def __init__(self):
self._data_1 = Thread(import_data(1)).start()
self._data_2 = Thread(import_data(2)).start()
def retrieve_data_1(self):
return self._data_1.wait_for_result()
def retrieve_data_2(self):
return self._data_2.wait_for_result()
import_data
函数在单独的线程和 return Future
对象中调用。
retrieve_data
函数要么阻塞主线程等待 Future
求值,要么立即 return 其结果。
在 Python 3.x 和 threading
and/or asyncio
中有没有一种简单的方法来实现这个?提前致谢!
(编辑:语法更正)
使用专为这种用途设计的 concurrent.futures
模块:
_pool = concurrent.futures.ThreadPoolExecutor()
class DataModel():
def __init__(self):
self._data_1 = _pool.submit(import_data, 1)
self._data_2 = _pool.submit(import_data, 2)
def retrieve_data_1(self):
return self._data_1.result()
def retrieve_data_2(self):
return self._data_2.result()
如果您的函数是全局的,并且您的数据是可序列化的,您甚至可以从 ThreadPoolExecutor
无缝切换到 ProcessPoolExecutor
并受益于真正的 (process-based) 并行性。
无法解决这个看似简单的问题,我有点沮丧:
我有一个函数需要一些时间来加载数据:
def import_data(id):
time.sleep(5)
return 'data' + str(id)
一个DataModel
class调用这个函数,管理两个数据集。
class DataModel():
def __init__(self):
self._data_1 = import_data(1)
self._data_2 = import_data(2)
def retrieve_data_1(self):
return self._data_1
def retrieve_data_2(self):
return self._data_2
现在,主要 UI 创建 DataModel
,调用两个 import_data
函数,这会阻止它。
def main_ui():
# This takes 5 seconds for each dataset and blocks the main UI thread
dm = DataModel()
# Other stuff is happening. This time could be used to load data in the background
time.sleep(2)
# Retrieve the first dataset
data_1 = dm.retrieve_data_1()
# User interaction. This time could be used to load even larger datasets
time.sleep(10)
# Retrieve the second dataset
data_2 = dm.retrieve_data_2()
我希望在后台加载数据集以减少 UI 被阻止的时间。 我的想法是像这样实现它 pseudocode:
class DataModel():
def __init__(self):
self._data_1 = Thread(import_data(1)).start()
self._data_2 = Thread(import_data(2)).start()
def retrieve_data_1(self):
return self._data_1.wait_for_result()
def retrieve_data_2(self):
return self._data_2.wait_for_result()
import_data
函数在单独的线程和 return Future
对象中调用。
retrieve_data
函数要么阻塞主线程等待 Future
求值,要么立即 return 其结果。
在 Python 3.x 和 threading
and/or asyncio
中有没有一种简单的方法来实现这个?提前致谢!
(编辑:语法更正)
使用专为这种用途设计的 concurrent.futures
模块:
_pool = concurrent.futures.ThreadPoolExecutor()
class DataModel():
def __init__(self):
self._data_1 = _pool.submit(import_data, 1)
self._data_2 = _pool.submit(import_data, 2)
def retrieve_data_1(self):
return self._data_1.result()
def retrieve_data_2(self):
return self._data_2.result()
如果您的函数是全局的,并且您的数据是可序列化的,您甚至可以从 ThreadPoolExecutor
无缝切换到 ProcessPoolExecutor
并受益于真正的 (process-based) 并行性。