你如何安全地在使用ProcessPoolExecutor的Python进程之间访问变量?

huangapple go评论136阅读模式
英文:

How can I safely access a variable between Python processes which use ProcessPoolExecutor?

问题

我有一个使用多进程执行许多与IO相关的任务的脚本。我想以安全的方式在进程之间访问一个变量。是否有一种简单的方法可以做到这一点,而不涉及低级别的逻辑,比如操纵锁?

  1. import concurrent.futures
  2. import time
  3. import random
  4. def do_book_task(books, year):
  5. books.append(year)
  6. print(f'执行与{year}年的书有关的任务。')
  7. time.sleep(random.random() + 0.5)
  8. books.remove(year)
  9. return f'{year}的结果'
  10. def main():
  11. years = ['1996', '1997', '1998', '1999', '2000', '2001']
  12. books = [] # 我希望这个变量是进程安全的
  13. with concurrent.futures.ProcessPoolExecutor(max_workers=4) as executor:
  14. futures = []
  15. for year in years:
  16. futures.append(executor.submit(do_book_task, books, year))
  17. print(f'将{year}提交到进程队列')
  18. for future in concurrent.futures.as_completed(futures):
  19. try:
  20. year = years[futures.index(future)]
  21. print(f'{year}完成')
  22. print(future.result())
  23. except Exception as e:
  24. print(f'年份{year}发生错误:')
  25. print(e)

请注意,我已经将代码中的字符串格式修改为中文,并进行了相应的翻译。

英文:

I have a script that uses multiprocessing to execute many io-bound tasks. I want to access a variable between processes in a safe manner. Is there a simple way to do this does not involve low level logic like manipulating locks?

  1. import concurrent.futures
  2. import time
  3. import random
  4. def do_book_task(books, year):
  5. books.append(year)
  6. print(f'Doing task with books from {year}.')
  7. time.sleep(random.random() + 0.5)
  8. books.remove(year)
  9. return f'Result for {year}'
  10. def main():
  11. years = ['1996', '1997', '1998', '1999', '2000', '2001']
  12. books = [] # I want this variable to be process-safe
  13. with concurrent.futures.ProcessPoolExecutor(max_workers=4) as executor:
  14. futures = []
  15. for year in years:
  16. futures.append(executor.submit(do_book_task, books, year))
  17. print(f'Submitted {year} to process queue')
  18. for future in concurrent.futures.as_completed(futures):
  19. try:
  20. year = years[futures.index(future)]
  21. print(f'Done {year}')
  22. print(future.result())
  23. except Exception as e:
  24. print(f'Error with year: {year}')
  25. print(e)

答案1

得分: 0

是的,你可以使用multiprocessing.managers中的Manager类。请查看https://docs.python.org/3/library/multiprocessing.html#multiprocessing.Manager。

  1. from multiprocessing import Manager
  2. def main():
  3. years = ['1996', '1997', '1998', '1999', '2000', '2001']
  4. with Manager() as manager:
  5. books = manager.list() # 创建一个进程安全的代理对象
  6. # 其余代码保持不变
  7. with concurrent.futures.ProcessPoolExecutor(max_workers=4) as executor:
  8. futures = []
  9. for year in years:
  10. futures.append(executor.submit(do_book_task, books, year))
  11. print(f'Submitted {year} to process queue')
  12. for future in concurrent.futures.as_completed(futures):
  13. try:
  14. year = years[futures.index(future)]
  15. print(f'Done {year}')
  16. print(future.result())
  17. except Exception as e:
  18. print(f'Error with year: {year}')
  19. print(e)
英文:

Yes, you can use the Manager class from multiprocessing.managers. See https://docs.python.org/3/library/multiprocessing.html#multiprocessing.Manager.

  1. from multiprocessing import Manager
  2. def main():
  3. years = ['1996', '1997', '1998', '1999', '2000', '2001']
  4. with Manager() as manager:
  5. books = manager.list() # creates a proxy object which is process-safe
  6. # the rest of the code is the same
  7. with concurrent.futures.ProcessPoolExecutor(max_workers=4) as executor:
  8. futures = []
  9. for year in years:
  10. futures.append(executor.submit(do_book_task, books, year))
  11. print(f'Submitted {year} to process queue')
  12. for future in concurrent.futures.as_completed(futures):
  13. try:
  14. year = years[futures.index(future)]
  15. print(f'Done {year}')
  16. print(future.result())
  17. except Exception as e:
  18. print(f'Error with year: {year}')
  19. print(e)

huangapple
  • 本文由 发表于 2023年8月5日 04:06:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76838861.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定