Python 3.x 在多线程应用程序中,在何处设置锁?
我正在尝试使用apply函数异步读取和写入数据。为此,我使用了Python 3.x 在多线程应用程序中,在何处设置锁?,python-3.x,multithreading,pandas,multiprocessing,apply,Python 3.x,Multithreading,Pandas,Multiprocessing,Apply,我正在尝试使用apply函数异步读取和写入数据。为此,我使用了多线程.dummy包。由于我在df上同时执行读写操作(多线程),因此我使用了多处理.Lock(),这样在给定时间内最多只能有一个线程可以编辑df。然而,我有点困惑,我应该在哪里添加一个lock.acquire()和lock.release()以及pandas中的apply函数。我试着按照下面的方法来做,但是,这样做似乎会使整个过程变得同步,因此它违背了多线程的全部目的 self._lock.acquire() to_df[col_na
多线程.dummy
包。由于我在df上同时执行读写操作(多线程),因此我使用了多处理.Lock()
,这样在给定时间内最多只能有一个线程
可以编辑df。然而,我有点困惑,我应该在哪里添加一个lock.acquire()
和lock.release()
以及pandas
中的apply
函数。我试着按照下面的方法来做,但是,这样做似乎会使整个过程变得同步
,因此它违背了多线程的全部目的
self._lock.acquire()
to_df[col_name] = to_df.apply(lambda row: getattr(Object(row['col_1'],
row['col_2'],
row['col_3']),
someattribute), axis=1)
self._lock.release()
注意:在我的情况下,我必须执行
getattr
someattribute
只是对象中的@属性
。对象接受3个参数,其中一些参数来自我的df的第1、2、3行。有两种可能的解决方案。1-锁。2-排队。下面的代码只是一个框架,可能包含打字错误,不能按原样使用
首先。在实际需要的地方锁定:
def method_to_process_url(df):
lock.acquire()
url = df.loc[some_idx, some_col]
lock.release()
info = process_url(url)
lock.acquire()
# add info to df
lock.release()
第二。队列而不是锁:
def method_to_process_url(df, url_queue, info_queue):
for url in url_queue.get():
info = process_url(url)
info_queue.put(info)
url_queue = queue.Queue()
# add all urls to process to the url_queue
info_queue = queue.Queue()
# working_thread_1
threading.Thread(
target=method_to_process_url,
kwargs={'url_queue': url_queue, 'info_queue': info_queue},
daemon=True).start()
# more working threads
counter = 0
while counter < amount_of_urls:
info = info_queue.get():
# add info to df
counter += 1
def方法到过程url(df、url队列、信息队列):
对于url_队列中的url.get():
info=进程\ url(url)
信息队列。放置(信息)
url\u queue=queue.queue()
#将要处理的所有url添加到url\u队列
info_queue=queue.queue()
#工作螺纹1
穿线,穿线(
目标=方法到进程的url,
kwargs={'url\u queue':url\u queue,'info\u queue':info\u queue},
daemon=True)
#更多的工作线程
计数器=0
当计数器
在第二种情况下,您甚至可以为每个url启动单独的线程,而不使用url\u queue
(如果url的数量在数千个或更少的顺序上,这是合理的)<代码>计数器是在处理所有URL时停止程序的简单方法
如果你问我,我会使用第二种方法。在我看来,它更灵活。异步执行的最初目的是什么?在Python(CPython)中,线程用于I/O绑定的操作(由于GIL),进程用于CPU绑定的操作。@Poolka所以我使用的Panda包含URL列,对于每个URL,它会调用不同的位置,然后将信息返回给DFT,然后更改设计-使用线程和队列将URL发送给工作线程,并将信息返回给主线程以将其合并到df中。锁是不需要的。@Poolka你会怎么做?我会把你的答案标记为正确的,但是,正如我发现的,熊猫在线程时是不安全的。看看这个。请看警告下的警告。@callmeGuy这根本不是问题。这些方法中的安全性是通过锁/队列实现的(锁是锁,队列是线程安全的)。在第二种方法中,数据帧仅在一个线程中处理。