我不知道如何解决这个似乎是随机发生的错误。我无法分享源代码,但如果有任何关于我可以采取哪些措施来防止此错误的想法,我将不胜感激。现在,我认为作为一种解决方法,我将捕获错误并重试...不确定这是否有效。就像上下文一样,我有一个生产者线程(显示问题的线程)填充数据帧以供消费者读取。这个问题看起来是随机的,因为它不容易重现。
Exception in thread Thread-3 (run_loop):
Traceback (most recent call last):
File "C:\Users\justi\AppData\Local\Programs\Python\Python312\Lib\threading.py", line 1073, in _bootstrap_inner
self.run()
File "C:\Users\justi\AppData\Local\Programs\Python\Python312\Lib\threading.py", line 1010, in run
self._target(*self._args, **self._kwargs)
File "g:\repos\stocks-projects\trading_bot\trading_bot.py", line 1027, in run_loop
bot.run()
File "G:\repos\stocks-projects\trading_bot\venv\Lib\site-packages\ibapi\client.py", line 263, in run
self.decoder.interpret(fields)
File "G:\repos\stocks-projects\trading_bot\venv\Lib\site-packages\ibapi\decoder.py", line 1387, in interpret
handleInfo.processMeth(self, iter(fields))
File "G:\repos\stocks-projects\trading_bot\venv\Lib\site-packages\ibapi\decoder.py", line 551, in processHistoricalDataUpdateMsg
self.wrapper.historicalDataUpdate(reqId, bar)
File "g:\repos\stocks-projects\trading_bot\trading_bot.py", line 230, in historicalDataUpdate
if bar.date in minute_data_df['date'].values:
~~~~~~~~~~~~~~^^^^^^^^
File "G:\repos\stocks-projects\trading_bot\venv\Lib\site-packages\pandas\core\frame.py", line 4078, in __getitem__
return self._get_item_cache(key)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "G:\repos\stocks-projects\trading_bot\venv\Lib\site-packages\pandas\core\frame.py", line 4639, in _get_item_cache
res = self._ixs(loc, axis=1)
^^^^^^^^^^^^^^^^^^^^^^
File "G:\repos\stocks-projects\trading_bot\venv\Lib\site-packages\pandas\core\frame.py", line 4010, in _ixs
col_mgr = self._mgr.iget(i)
^^^^^^^^^^^^^^^^^
File "G:\repos\stocks-projects\trading_bot\venv\Lib\site-packages\pandas\core\internals\managers.py", line 1016, in iget
block = self.blocks[self.blknos[i]]
^^^^^^^^^^^
File "G:\repos\stocks-projects\trading_bot\venv\Lib\site-packages\pandas\core\internals\managers.py", line 192, in blknos
self._rebuild_blknos_and_blklocs()
File "internals.pyx", line 784, in pandas._libs.internals.BlockManager._rebuild_blknos_and_blklocs
AssertionError: Gaps in blk ref_locs
“blk ref_locs 中的间隙”断言错误是一个 Pandas 错误,通常在多线程环境中并发修改 Pandas DataFrame 时发生,而未进行适当的同步。这个错误表明 Pandas DataFrame 的内部数据结构已损坏,这可能是因为多个线程同时写入 DataFrame 或一个线程修改了另一个线程正在读取的 DataFrame 造成的。
鉴于你无法共享代码,我可以提供一些通用的调试步骤和解决方案:
1. 识别并发访问
- 检查生产者-消费者逻辑: 仔细检查生产者线程填充 DataFrame 和消费者线程访问 DataFrame 之间的定时和同步。寻找可能出现竞争条件的区域,其中两个线程可能同时尝试修改 DataFrame。
- 打印语句/日志: 在生产者和消费者线程中添加打印语句或日志,以跟踪 DataFrame 访问和修改。这可以帮助你识别错误发生之前发生的事件序列并查明并发访问。
2. 实现同步
-
线程锁: 使用线程锁(例如
threading.Lock
)以保护对 DataFrame 的关键部分的访问。在修改 DataFrame 之前获取锁,并在完成后释放锁。 ```python import threadingdata_lock = threading.Lock()
生产者线程
with data_lock: # 修改 DataFrame
消费者线程
with data_lock: # 访问 DataFrame ```
-
队列: 考虑使用队列(例如
queue.Queue
)在生产者和消费者线程之间安全地传递数据。生产者线程可以将数据放入队列中,而消费者线程可以从队列中读取数据,从而无需直接访问共享的 DataFrame。 ```python import queuedata_queue = queue.Queue()
生产者线程
data_queue.put(data_frame)
消费者线程
data_frame = data_queue.get() ```
3. 替代解决方案
-
深度复制: 在将其传递给消费者线程之前,为消费者线程创建一个 DataFrame 的深度副本。这可以防止并发修改原始 DataFrame,但会带来额外的开销。 ```python import copy
生产者线程
consumer_df = copy.deepcopy(producer_df) ```
-
线程安全数据结构: 探索使用线程安全数据结构(例如来自
collections
模块的字典或列表)来代替 Pandas DataFrame,尤其是在 DataFrame 的大小很大且性能受到影响的情况下。
4. 调试和测试
- 最小化代码: 尝试创建一个最小、可重现的代码示例,以隔离问题并排除其他因素。
- 调试器: 使用调试器逐步执行代码并检查变量,以识别并发修改发生的位置。
- 压力测试: 使用多线程负载对代码进行压力测试,以增加发生错误的可能性并帮助你识别计时问题。
记住,在没有访问源代码的情况下,很难提供更具体的建议。但是,通过遵循这些通用调试步骤并实现适当的同步机制,你应该能够解决“blk ref_locs 中的间隙”错误并提高多线程 Python 代码的稳定性。
标签:python,multithreading,debugging,ib-api From: 78786183