我一直在大量使用线程(并行处理)和锁(防止同时操作共享对象)。由于我正在以并行线程的极高处理速度编写代码,接收数据并填充共享数据缓冲区,我想知道什么时候真的需要锁?你知道吗
我知道第三种情况主要很关键(给出了著名的线程和锁的“增量计数器”示例)。但在其他情况下我也应该使用锁吗?你知道吗
在我的特殊情况下,它是关于一个用作数据缓冲区的数据帧。我想:
下面的最小工作示例(MWE)用线程显示了这个进程,但是为了简单起见,这里是按顺序处理的,并且进程之间有密集的锁。虽然这是一个非常谨慎的方法,但我想有些获取/释放锁的步骤可能会被放弃?但由于pandas在附加对象时正在复制对象,所以我不能100%确定是否要删除这些锁。你知道吗
有没有人对此进行过深入的测试,或者有没有人对此有过经验?你知道吗
中全景:
import pandas as pd
import threading
thread_lock = threading.Lock()
df_data_buffer = pd.DataFrame({"key" : []})
def add_data_to_buffer(df_data_ingestion):
global df_data_buffer
thread_lock.acquire()
df_data_buffer = df_data_buffer.append(df_data_ingestion)
thread_lock.release()
def get_data_from_buffer(key):
thread_lock.acquire()
df_data_buffer.reset_index(inplace=True, drop=True) #required for proper dropping by index
df_extracted = df_data_buffer.loc[df_data_buffer["key"] == key].copy()
thread_lock.release()
drop_data(df_extracted.index)
return df_extracted
def drop_data_from_buffer(df_index):
global df_data_buffer
thread_lock.acquire()
df_data_buffer.drop(df_index, inplace=True)
thread_lock.release()
return True
df_data1 = pd.DataFrame({"key" : [1]})
t_add_data1 = threading.Thread(target=add_data, args=[df_data1])
t_add_data1.start()
t_add_data1.join()
print "*"*10, 1, "*"*10
print df_data_buffer
df_data2 = pd.DataFrame({"key" : [2]})
t_add_data2 = threading.Thread(target=add_data, args=[df_data2])
t_add_data2.start()
t_add_data2.join()
print "*"*10, 2, "*"*10
print df_data_buffer
key=1
df_data_extracted = get_data(key)
print "*"*10, "extract", "*"*10
print "df_data_extracted\n", df_data_extracted
print "df_data_buffer\n", df_data_buffer
print "*"*10, 3, "*"*10
df_data3 = pd.DataFrame({"key" : [3]})
t_add_data3 = threading.Thread(target=add_data, args=[df_data3])
t_add_data3.start()
t_add_data3.join()
print df_data_buffer
输出:
********** 1 **********
key
0 1.0
********** 2 **********
key
0 1.0
1 2.0
********** extract **********
df_data_extracted
key
0 1.0
df_data_buffer
key
1 2.0
********** 3 **********
key
0 2.0
1 3.0
你选择什么对你很重要。执行读取时,是否需要最新数据。例如,您可以选择在读取数据帧时不包含锁,而在一些计算之后重新分配数据帧时只包含锁。但是,您似乎需要完全的一致性保证,而您当前的锁定规程可以很好地使用这种保证。此外,当从多个线程写入数据时,pandas DataFrame没有内部一致性保证,因此必须在这样做时锁定。你知道吗
但是,您还必须意识到} 或全局解释器锁,只允许在任何给定时间执行一个python“线程”。要获得实际的并行性,必须使用从} 。由于这个事实,我怀疑上面的代码执行速度是否比在单个线程中运行这个操作快。你知道吗
cpython
实现使用了^{GIL
中解放出来的^{相关问题 更多 >
编程相关推荐