use*_*956 5 python multithreading pandas
调用pd.Series.reindex不是线程安全的(https://github.com/pandas-dev/pandas/issues/25870)。我的问题是,即使没有人写入该对象的数据,为什么Series.reindex(它返回一个副本并且看起来像是一个纯功能操作)不是线程安全的?
我正在执行的操作是:
s = pd.Series(...)
f(s) # Success!
# Thread 1:
while True: f(s)
# Thread 2:
while True: f(s) # Exception !
Run Code Online (Sandbox Code Playgroud)
... f(s) 失败:s.reindex(..., copy=True)。
那么,为什么线程调用失败了呢?我对此感到惊讶,因为如果有任何线程不安全的调用,例如填充系列的索引,我会认为这些会在主线程中完成它们的变异工作。
Pandas确实有一个未解决的问题,.copy它不是线程安全的。然而,这里的讨论是围绕着人们同时读取和写入对象的问题。
https://github.com/pandas-dev/pandas/issues/2728
维护者将.reindex非线程安全问题标记为https://github.com/pandas-dev/pandas/issues/2728的副本 。我怀疑它有相同的原因,但如果.copy是来源,那么我怀疑几乎所有的熊猫在任何情况下都不是线程安全的,对于“功能纯”的操作。
import traceback
import pandas as pd
import numpy as np
from multiprocessing.pool import ThreadPool
def f(arg):
s,idx = arg
try:
# s.loc[idx].values # No problem
s.reindex(idx) # Fails
except Exception:
traceback.print_exc()
return None
def gen_args(n=10000):
a = np.arange(0, 3000000)
for i in xrange(n):
if i%1000 == 0:
# print "?",i
s = pd.Series(data=a, index=a)
f((s,a)) # <<< LOOK. IT WORKS HERE!!!
yield s, np.arange(0,1000)
# for arg in gen_args():
# f(arg) # Works fine
t = ThreadPool(4)
for result in t.imap(f, gen_args(), chunksize=1):
# print "==>", result
pass
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
136 次 |
| 最近记录: |