我有 28 種方法正在池中運行。ThreadPoolExecutor 總共創建了 28 個執行緒,ThreadPoolExecutor 是一個 Executor 子類,它使用執行緒池來異步執行呼叫。在執行緒執行期間,我正在使用 Plotly 生成一些圖表。我遇到的問題是 ThreadPoolExecutor 在所有執行緒實際完成之前完成。我總是遇到 4 個未創建(未完成)的圖表(執行緒)。這是我的代碼:
from concurrent.futures import ThreadPoolExecutor
pool = ThreadPoolExecutor(max_workers=len(methods))
for method in methods:
pool.submit(method, commits, system_name, reset, chart_output)
pool.shutdown(wait=True)
執行的方法如下所示:
def commits_by_date(commits, system_name, reset, chart_output):
collection_name = "commits_by_date"
reset_db_data(reset, system_name, collection_name)
date_commits = retrieve_db_data(system_name, collection_name)
if len(date_commits) == 0:
date_commits = commits.groupby('commit_date')[['sha']].count()
date_commits = date_commits.rename(columns={'sha': 'commit_count'})
date_commits.insert(0, "system_name", system_name)
date_commits = date_commits.reset_index()
save_df_to_db(date_commits, collection_name)
if chart_output:
fig = go.Figure([go.Scatter(
x=date_commits.commit_date,
y=date_commits.commit_count,
text=date_commits.commit_count,
fill='tozeroy')])
fig.update_layout(
title='Commits by Date',
yaxis_title='Commits Count')
fig.write_html('commits_by_date.html', auto_open=True)
uj5u.com熱心網友回復:
這取決于method在做什么。使用并發時,必須避免共享可變狀態。您嘗試同時執行的函式似乎訪問了 plotly 圖,這是一個共享的可變狀態。
為避免出現問題,您應該只制作可重入的并發代碼,并且部分更改共享狀態的代碼應該同步執行。
實作這一點的一種方法是分解method為兩個函式:第一個函式執行您想要并行化的繁重作業(并且必須是可重入的),第二個函式同步繪制結果。
這是一個如何使用 Pythonconcurrent.futures模塊實作此目的的示例:
from concurrent.futures import ThreadPoolExecutor, as_completed
def heavy_work(arg):
# Some heavy work...
result = slow_function(arg)
return result
def plot(result, figure):
# Plot the result to a shared figure,
# must be executed synchronously.
figure.plot(result)
args = [...] # List of arguments to `heavy_work`
figure = ... # The shared figure
# Submit work to be executed concurrently
with ThreadPoolExecutor() as pool:
futures = [pool.submit(heavy_work, arg) for arg in args]
# Serialize the calls to `plot`
for future in as_completed(futures):
result = future.result()
plot(result, figure)
uj5u.com熱心網友回復:
答案是使用:
import time
for method in methods:
pool.submit(method, commits, system_name, reset, chart_output)
time.sleep(as_many_you_want)
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/412306.html
標籤:
