我在 Web 服务器(apache + modwsgi + django)上使用 pandas
并且有一个难以重现的错误,现在我发现它是由 pandas 不是线程安全的引起的。
经过大量代码缩减后,我终于找到了一个简短的独立程序,可用于重现该问题。你可以在下面看到它。
重点是:与this question的回答相反这个例子表明,即使使用不修改数据帧的非常简单的操作,pandas 也可能会崩溃。我无法想象这个简单的代码片段怎么可能对线程不安全...
问题是关于在网络服务器中使用 pandas 和 numpy。可能吗?我应该如何使用 Pandas 修复我的代码? (使用锁的示例会有所帮助)
这是导致段错误的代码:
import threading
import pandas as pd
import numpy as np
def let_crash(crash=True):
t = 0.02 * np.arange(100000) # ok con 10000
data = pd.DataFrame({'t': t})
if crash:
data['t'] * 1.5 # CRASH
else:
data['t'].values * 1.5 # THIS IS OK!
if __name__ == '__main__':
threads = []
for i in range(100):
if True: # asynchronous
t = threading.Thread(target=let_crash, args = ())
t.daemon = True
t.start()
threads.append(t)
else: # synchronous
let_crash()
for t in threads:
t.join()
我的环境:python 2.7.3,numpy 1.8.0,pandas 0.13.1
最佳答案
请参阅此处文档中的警告:http://pandas.pydata.org/pandas-docs/dev/gotchas.html#thread-safety
pandas 不是线程安全的,因为底层的复制机制不是。我相信 Numpy 有一个原子复制操作,但 pandas 在这上面有一层。
Copy是pandas操作的基础(因为大多数操作都会生成一个新的对象返回给用户)
修复此问题并非易事,并且会带来相当高的性能成本,因此需要做一些工作才能正确处理此问题。
最简单的方法就是不跨线程共享对象或在使用时锁定它们。
关于python - Pandas 和 numpy 线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25782912/