これはあなたのproject from yesterdayあなたは既にメモリにダウンロードリストを持っているの継続であれば - ちょうど彼らのプロセスは、ダウンロードを終えると、ロードされたリストからエントリを削除し、のみ、入力ファイル上の全リストを書き留め一度あなたは 'ダウンローダ'を終了しています。常に変更を書き留める必要はありません。
「ダウンローダ」の実行中にもURLがダウンロードされたときに(外部プロセスから)知りたい場合は、そのダウンロードが成功するたびにdownloaded.dat
に改行が書き込まれます。
もちろん、どちらの場合でも、メインプロセス/スレッド内から書き込みを行い、mutexについて心配する必要はありません。
UPDATE - ここでは昨日と同じコードベースを使用して、追加のファイルでそれを行う方法は次のとおりです。
def init_downloader(params): # our downloader initializator
downloader = Downloader(**params[0]) # instantiate our downloader
downloader.run(params[1]) # run our downloader
return params # job finished, return the same params for identification
if __name__ == "__main__": # important protection for cross-platform use
downloader_params = [ # Downloaders will be initialized using these params
{"port_number": 7751},
{"port_number": 7851},
{"port_number": 7951}
]
downloader_cycle = cycle(downloader_params) # use a cycle for round-robin distribution
with open("downloaded_links.dat", "a+") as diff_file: # open your diff file
diff_file.seek(0) # rewind the diff file to the beginning to capture all lines
diff_links = {row.strip() for row in diff_file} # load downloaded links into a set
with open("input_links.dat", "r+") as input_file: # open your input file
available_links = []
download_jobs = [] # store our downloader parameters + a link here
# read our file line by line and filter out downloaded links
for row in input_file: # loop through our file
link = row.strip() # remove the extra whitespace to get the link
if link not in diff_links: # make sure link is not already downloaded
available_links.append(row)
download_jobs.append([next(downloader_cycle), link])
input_file.seek(0) # rewind our input file
input_file.truncate() # clear out the input file
input_file.writelines(available_links) # store back the available links
diff_file.seek(0) # rewind the diff file
diff_file.truncate() # blank out the diff file now that the input is updated
# and now let's get to business...
if download_jobs:
download_pool = Pool(processes=5) # make our pool use 5 processes
# run asynchronously so we can capture results as soon as they ar available
for response in download_pool.imap_unordered(init_downloader, download_jobs):
# since it returns the same parameters, the second item is a link
# add the link to our `diff` file so it doesn't get downloaded again
diff_file.write(response[1] + "\n")
else:
print("Nothing left to download...")
私は、ファイルを使用するために、コメントに書いたように全体的なアイデアは、ありますダウンロードされたリンクをダウンロードして保存し、次回の実行時にダウンロードしたリンクをフィルタリングして入力ファイルを更新します。そうすれば、強制的に強制終了しても、中断したところから再開します(部分ダウンロードを除く)。
これは、問題を処理するのに特に困難な方法のようです。これらの仕事は何ですか?おそらくそれが問題を処理する最良の方法です。 csvを一度消費してジョブを作成します(たぶん、データベースや別々のファイルに保存されます)。それらを管理します。csvのことをしたいのであれば、作業者からの応答が送信され、csvファイルが更新される単一のエンティティ(おそらくジョブを扱うマスタープログラム)によってのみ管理されるべきです。 – tdelaney
あなたはしません。複数の(平行な)コントロールポイントからの副作用を処理することは、災害のためのレシピです。それを動作させる*唯一の方法であれば、あなたの現在の答えのいくつかが示唆しているようにロックを実装できますが、ここではそうではないようです。マネージャ/ワーカーパターンを実装し、マネージャにIOを渡し、ジョブをワーカーに渡し、ワーカーから結果を受け取らせる必要があります。 –