concurrent.futures --- راهاندازی وظایف موازی¶
اضافه شده در نسخهی 3.2.
کد منبع: Lib/concurrent/futures/thread.py، Lib/concurrent/futures/process.py و Lib/concurrent/futures/interpreter.py
ماژول concurrent.futures یک رابط سطح بالا برای اجرای ناهمگام فراخوانیپذیرها فراهم میکند.
اجرای ناهمگام را میتوان با نخها، با استفاده از ThreadPoolExecutor یا InterpreterPoolExecutor، یا با فرآیندهای جداگانه، با استفاده از ProcessPoolExecutor انجام داد. هر یک از آنها رابط یکسانی را پیادهسازی میکند که توسط کلاس انتزاعی Executor تعریف شده است.
concurrent.futures.Future نباید با asyncio.Future اشتباه گرفته شود، که برای استفاده با وظایف و همروالهای asyncio طراحی شده است. برای مقایسهی دقیق این دو، مستندات Future در asyncio را ببینید.
دسترسپذیری: not WASI.
این ماژول روی WebAssembly کار نمیکند یا در دسترس نیست. برای اطلاعات بیشتر سکوهای WebAssembly را ببینید.
اشیای Executor¶
- class concurrent.futures.Executor¶
یک کلاس انتزاعی که متدهایی برای اجرای فراخوانیها بهصورت ناهمگام فراهم میکند. این کلاس نباید مستقیماً استفاده شود، بلکه باید از طریق زیرکلاسهای عینی آن استفاده شود.
- submit(fn, /, *args, **kwargs)¶
شیء فراخوانیپذیر fn را زمانبندی میکند تا بهصورت
fn(*args, **kwargs)اجرا شود و یک شیءFutureرا برمیگرداند که نشاندهندهی اجرای آن شیء فراخوانیپذیر است.with ThreadPoolExecutor(max_workers=1) as executor: future = executor.submit(pow, 323, 1235) print(future.result())
- map(fn, *iterables, timeout=None, chunksize=1, buffersize=None)¶
مشابه
map(fn, *iterables)با این تفاوت که:iterables بهجای جمعآوری بهصورت تنبل، بلافاصله جمعآوری میشوند، مگر اینکه buffersize برای محدود کردن تعداد وظایف ارسالشدهای که نتایجشان هنوز تولید نشدهاند تعیین شده باشد. اگر بافر پر باشد، پیمایش بر iterables تا زمانی که نتیجهای از بافر تولید شود متوقف میشود.
fn بهصورت ناهمگام اجرا میشود و ممکن است چندین فراخوانی fn بهصورت همزمان انجام شود.
اگر
__next__()فراخوانی شود و نتیجه پس از گذشت timeout ثانیه از فراخوانی اصلیExecutor.map()در دسترس نباشد، پیمایشگر برگرداندهشده استثنایTimeoutErrorرا پرتاب میکند. timeout میتواند یک عدد صحیح یا عدد اعشاری باشد. اگر timeout مشخص نشده باشد یاNoneباشد، محدودیتی برای زمان انتظار وجود ندارد.اگر یک فراخوانی fn استثنایی را پرتاب کند، آن استثنا زمانی پرتاب خواهد شد که مقدارش از پیمایشگر بازیابی شود.
هنگام استفاده از
ProcessPoolExecutor، این متد پیمایشپذیرها را به تعدادی تکه تقسیم میکند و آنها را بهعنوان وظایف جداگانه به استخر ارسال میکند. اندازهی (تقریبی) این تکهها را میتوان با تنظیم chunksize روی یک عدد صحیح مثبت مشخص کرد. برای پیمایشپذیرهای بسیار طولانی، استفاده از یک مقدار بزرگ برای chunksize میتواند در مقایسه با اندازهی پیشفرض ۱، عملکرد را بهطور قابلتوجهی بهبود بخشد. درThreadPoolExecutorوInterpreterPoolExecutor، chunksize هیچ تأثیری ندارد.تغییر یافته در نسخهی 3.5: پارامتر chunksize افزوده شد.
تغییر یافته در نسخهی 3.14: پارامتر buffersize افزوده شد.
- shutdown(wait=True, *, cancel_futures=False)¶
به اجراکننده (executor) اطلاع میدهد که باید هر منبعی را که در حال استفاده از آن است، هنگامی که اجرای آیندهنماهای در انتظار فعلی (futures) به پایان رسید، آزاد کند. فراخوانیهای
Executor.submit()وExecutor.map()که پس از shutdown انجام شوند،RuntimeErrorرا پرتاب خواهند کرد.اگر wait برابر
Trueباشد، این متد تا زمانی که اجرای تمام آیندهنماهای در انتظار (futures) به پایان نرسیده باشد و منابع مرتبط با اجراکننده (executor) آزاد نشده باشند، بازگشت نخواهد کرد. اگر wait برابرFalseباشد، این متد بلافاصله بازمیگردد و منابع مرتبط با اجراکننده زمانی آزاد میشوند که اجرای تمام آیندهنماهای در انتظار به پایان برسد. صرفنظر از مقدار wait، کل برنامه پایتون تا زمانی که اجرای تمام آیندهنماهای در انتظار به پایان نرسیده باشد، خارج نخواهد شد.اگر cancel_futures برابر
Trueباشد، این متد تمام آیندهنماهای در انتظار را که اجراکننده اجرای آنها را آغاز نکرده است، لغو میکند. آیندهنماهایی که تکمیل شدهاند یا در حال اجرا هستند، بدون توجه به مقدار cancel_futures لغو نخواهند شد.اگر هر دو cancel_futures و wait برابر
Trueباشند، تمام آیندهنماهایی که اجراکننده اجرای آنها را آغاز کرده است، پیش از بازگشت این متد تکمیل خواهند شد. آیندهنماهای باقیمانده لغو میشوند.اگر از اجراکننده بهعنوان یک context manager از طریق دستور
withاستفاده کنید، نیازی به فراخوانی صریح این متد نخواهید داشت؛ در این حالتExecutorخاموش میشود (منتظر میماند، گوییExecutor.shutdown()با wait رویTrueفراخوانی شده است):import shutil with ThreadPoolExecutor(max_workers=4) as e: e.submit(shutil.copy, 'src1.txt', 'dest1.txt') e.submit(shutil.copy, 'src2.txt', 'dest2.txt') e.submit(shutil.copy, 'src3.txt', 'dest3.txt') e.submit(shutil.copy, 'src4.txt', 'dest4.txt')
تغییر یافته در نسخهی 3.9: cancel_futures اضافه شد.
ThreadPoolExecutor¶
ThreadPoolExecutor یک زیرکلاس از Executor است که از استخری از نخها برای اجرای فراخوانیها بهصورت ناهمگام استفاده میکند.
بنبستها ممکن است زمانی رخ دهند که فراخوانیپذیر مرتبط با یک Future منتظر نتایج یک Future دیگر بماند. برای مثال:
import time
def wait_on_b():
time.sleep(5)
print(b.result()) # b will never complete because it is waiting on a.
return 5
def wait_on_a():
time.sleep(5)
print(a.result()) # a will never complete because it is waiting on b.
return 6
executor = ThreadPoolExecutor(max_workers=2)
a = executor.submit(wait_on_b)
b = executor.submit(wait_on_a)
و:
def wait_on_future():
f = executor.submit(pow, 5, 2)
# This will never complete because there is only one worker thread and
# it is executing this function.
print(f.result())
executor = ThreadPoolExecutor(max_workers=1)
future = executor.submit(wait_on_future)
# Note: calling future.result() would also cause a deadlock because
# the single worker thread is already waiting for wait_on_future().
- class concurrent.futures.ThreadPoolExecutor(max_workers=None, thread_name_prefix='', initializer=None, initargs=())¶
یک زیرکلاس
Executorکه از استخری با حداکثر max_workers نخ برای اجرای فراخوانیها بهصورت ناهمگام استفاده میکند.پیش از آنکه مفسر بتواند خارج شود، همه نخهایی که در
ThreadPoolExecutorدر صف قرار گرفتهاند، join خواهند شد. توجه داشته باشید که هندلر خروجی که این کار را انجام میدهد، پیش از هر هندلر خروجی که با استفاده ازatexitاضافه شده باشد، اجرا میشود. این بدان معناست که برای علامتدهی به نخها جهت خروج بهصورت ایمن، باید استثناهای نخ اصلی گرفته و مدیریت شوند. به همین دلیل، توصیه میشود کهThreadPoolExecutorبرای وظایف طولانیمدت استفاده نشود.initializer یک شیء فراخوانیپذیر اختیاری است که در آغاز هر نخکارگر فراخوانی میشود؛ initargs تاپلی از آرگومانها است که به initializer ارسال میشوند. در صورتی که initializer استثنایی پرتاب کند، همه کارهایی که در حال حاضر در انتظار هستند، و همچنین هر تلاشی برای ارسال کارهای بیشتر به استخر، یک
BrokenThreadPoolپرتاب خواهند کرد.تغییر یافته در نسخهی 3.5: اگر max_workers
Noneباشد یا ارائه نشود، بهطور پیشفرض برابر با تعداد پردازندههای ماشین ضرب در5خواهد بود، با این فرض کهThreadPoolExecutorاغلب برای همپوشانی ورودی/خروجی بهجای کار پردازنده استفاده میشود و تعداد کارگرها باید بیشتر از تعداد کارگرهایProcessPoolExecutorباشد.تغییر یافته در نسخهی 3.6: پارامتر thread_name_prefix افزوده شد تا کاربران بتوانند نامهای
threading.Threadرا برای نخهای کارگر ایجادشده توسط استخر، برای اشکالزدایی آسانتر کنترل کنند.تغییر یافته در نسخهی 3.7: آرگومانهای initializer و initargs اضافه شدند.
تغییر یافته در نسخهی 3.8: مقدار پیشفرض max_workers به
min(32, os.cpu_count() + 4)تغییر کرده است. این مقدار پیشفرض حداقل ۵ کارگر را برای وظایف محدود به I/O حفظ میکند. این مقدار حداکثر از ۳۲ هستهی CPU برای وظایف محدود به CPU که GIL را آزاد میکنند، استفاده میکند. و از استفادهی ضمنی از منابع بسیار زیاد در ماشینهای با تعداد هسته بسیار زیاد جلوگیری میکند.ThreadPoolExecutor اکنون پیش از راهاندازی max_workers نخ کاری، از نخهای کاری بیکار نیز دوباره استفاده میکند.
تغییر یافته در نسخهی 3.13: مقدار پیشفرض max_workers به
min(32, (os.process_cpu_count() or 1) + 4)تغییر کرده است.
مثال ThreadPoolExecutor¶
import concurrent.futures
import urllib.request
URLS = ['http://www.foxnews.com/',
'http://www.cnn.com/',
'http://europe.wsj.com/',
'http://www.bbc.co.uk/',
'http://nonexistent-subdomain.python.org/']
# Retrieve a single page and report the URL and contents
def load_url(url, timeout):
with urllib.request.urlopen(url, timeout=timeout) as conn:
return conn.read()
# We can use a with statement to ensure threads are cleaned up promptly
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
# Start the load operations and mark each future with its URL
future_to_url = {executor.submit(load_url, url, 60): url for url in URLS}
for future in concurrent.futures.as_completed(future_to_url):
url = future_to_url[future]
try:
data = future.result()
except Exception as exc:
print('%r generated an exception: %s' % (url, exc))
else:
print('%r page is %d bytes' % (url, len(data)))
InterpreterPoolExecutor¶
اضافه شده در نسخهی 3.14.
کلاس InterpreterPoolExecutor از استخری از مفسرها استفاده میکند تا فراخوانیها را بهصورت ناهمگام اجرا کند. این کلاس یک زیرکلاس از ThreadPoolExecutor است، که به این معناست که هر کارگر در نخ خود اجرا میشود. تفاوت در اینجا این است که هر کارگر مفسر خود را دارد و هر وظیفه را با استفاده از آن مفسر اجرا میکند.
بزرگترین مزیت استفاده از مفسرها بهجای استفاده صرف از نخها، موازیسازی چندهستهای واقعی است. هر مفسر دارای قفل سراسری مفسر مختص خود است، بنابراین کد در حال اجرا در یک مفسر میتواند بر یک هستهی CPU اجرا شود، در حالی که کد در مفسری دیگر بدون مسدود شدن بر هستهی دیگری اجرا میشود.
بهای این کار آن است که نوشتن کد همروند برای استفاده با چندین مفسر ممکن است تلاش بیشتری بطلبد. با این حال، دلیل این موضوع آن است که این کار شما را ملزم میکند دربارهی چگونگی و زمان تعامل مفسرها با یکدیگر سنجیده عمل کنید و بهصراحت مشخص کنید چه دادههایی بین مفسرها مشترک است. این امر چندین مزیت به همراه دارد که به جبران این تلاش اضافی کمک میکنند، از جمله موازیسازی واقعی چند هستهای. برای مثال، کدی که به این شیوه نوشته شده باشد میتواند استدلال دربارهی همروندی را آسانتر کند. مزیت مهم دیگر این است که شما مجبور نیستید با چندین نقطهی دردساز بزرگ استفاده از نخها، مانند شرایط رقابتی، سروکار داشته باشید.
مفسر هر کارگر از همه مفسرهای دیگر ایزوله است. «ایزوله» یعنی هر مفسر وضعیت رانتایم خودش را دارد و بهطور کاملاً مستقل عمل میکند. برای مثال، اگر sys.stdout را در یک مفسر تغییر مسیر دهید، این تغییر مسیر بهطور خودکار در هیچ مفسر دیگری اعمال نمیشود. اگر ماژولی را در یک مفسر ایمپورت کنید، بهطور خودکار در هیچ مفسر دیگری ایمپورت نمیشود. لازم است آن ماژول را بهطور جداگانه در مفسری که به آن نیاز دارید ایمپورت کنید. در واقع، هر ماژول ایمپورتشده در یک مفسر، یک شیء کاملاً جدا از همان ماژول در مفسری دیگر است، از جمله sys، builtins و حتی __main__.
جداسازی به این معناست که نمیتوان همزمان از یک شیء تغییرپذیر، یا دادههای دیگر، در بیش از یک مفسر استفاده کرد. این عملاً به این معناست که مفسرها در واقع نمیتوانند چنین اشیاء یا دادههایی را به اشتراک بگذارند. در عوض، هر مفسر باید نسخهی خود را داشته باشد و شما باید هرگونه تغییر بین نسخهها را بهصورت دستی همگامسازی کنید. اشیاء و دادههای تغییرناپذیر، مانند تکنمونههای توکار، رشتهها و تاپلهایی از اشیاء تغییرناپذیر، این محدودیتها را ندارند.
ارتباط و همگامسازی بین مفسرها به مؤثرترین سینتکس با استفاده از ابزارهای اختصاصی انجام میشود، مانند آنهایی که در PEP 734 پیشنهاد شدهاند. یک جایگزین کمبازدهتر، سریالسازی با pickle و سپس ارسال بایتها از طریق یک socket یا pipe مشترک است.
- class concurrent.futures.InterpreterPoolExecutor(max_workers=None, thread_name_prefix='', initializer=None, initargs=())¶
زیرکلاسی از
ThreadPoolExecutorکه فراخوانیها را بهصورت ناهمگام با استفاده از استخری از حداکثر max_workers نخ اجرا میکند. هر نخ وظایف را در مفسر خود اجرا میکند. مفسرهای کارگر از یکدیگر جدا هستند، که یعنی هر مفسر وضعیت رانتایم خود را دارد و نمیتواند هیچ شیء تغییرپذیر یا داده دیگری را به اشتراک بگذارد. هر مفسر دارای قفل سراسری مفسر خود است، که یعنی کدی که با این اجراکننده اجرا میشود، از موازیسازی چندهستهای واقعی برخوردار است.آرگومانهای اختیاری initializer و initargs همان معنایی را دارند که برای
ThreadPoolExecutorدارند: initializer هنگام ایجاد هر کارگر اجرا میشود، هرچند در این حالت در مفسر کارگر اجرا میشود. اجراکننده، initializer و initargs را هنگام ارسال آنها به مفسر کارگر با استفاده ازpickleسریالسازی میکند.توجه
اجراکننده ممکن است استثناهای گرفتهنشده از initializer را با
ExecutionFailedجایگزین کند.سایر نکات احتیاطی مربوط به کلاس والد
ThreadPoolExecutorدر اینجا نیز اعمال میشوند.
submit() و map() مانند حالت عادی کار میکنند، با این تفاوت که کارگر، شیء فراخوانیپذیر و آرگومانها را هنگام ارسال آنها به مفسر خود، با استفاده از pickle سریالسازی میکند. کارگر نیز به همین ترتیب مقدار بازگشتی را هنگام بازگرداندن آن سریالسازی میکند.
هنگامی که وظیفه فعلی یک کارگر یک استثنای گرفتهنشده پرتاب میکند، کارگر همیشه تلاش میکند استثنا را بههمانصورت حفظ کند. اگر این کار موفقیتآمیز باشد، __cause__ را نیز به یک نمونه متناظر از ExecutionFailed تنظیم میکند که شامل خلاصهای از استثنای اصلی است. در حالت غیرمعمولی که کارگر نتواند استثنای اصلی را بههمانصورت حفظ کند، در عوض نمونه متناظر از ExecutionFailed را مستقیماً حفظ میکند.
ProcessPoolExecutor¶
کلاس ProcessPoolExecutor یک زیرکلاس از Executor است که از استخری از فرایندها برای اجرای ناهمگام فراخوانیها استفاده میکند. ProcessPoolExecutor از ماژول multiprocessing استفاده میکند؛ این ماژول امکان دور زدن قفل مفسر سراسری را فراهم میکند، اما همچنین به این معناست که فقط اشیای پیکلپذیر میتوانند اجرا یا بازگردانده شوند.
ماژول __main__ باید توسط زیرفرایندهای کارگر قابل ایمپورت باشد. این بدان معناست که ProcessPoolExecutor در مفسر تعاملی کار نخواهد کرد.
فراخوانی متدهای Executor یا Future از یک شیء فراخوانیپذیر که به ProcessPoolExecutor ارسالشده است، منجر به بنبست میشود.
توجه داشته باشید که محدودیتهای مربوط به پیکلپذیری بودن توابع و آرگومانها، مطابق multiprocessing.Process، هنگام استفاده از submit() و map() بر روی ProcessPoolExecutor اعمال میشوند. نباید انتظار داشته باشید که تابعی که در یک REPL یا بهصورت یک lambda تعریف شده است، کار کند.
- class concurrent.futures.ProcessPoolExecutor(max_workers=None, mp_context=None, initializer=None, initargs=(), max_tasks_per_child=None)¶
یک کلاس فرعی از
Executorکه فراخوانیها را بهصورت ناهمگام با استفاده از استخری از حداکثر max_workers فرآیند اجرا میکند. اگر max_workers برابرNoneباشد یا داده نشود، مقدار پیشفرض آنos.process_cpu_count()خواهد بود. اگر max_workers کمتر یا مساوی با0باشد، یکValueErrorپرتاب خواهد شد. در ویندوز، max_workers باید کمتر یا مساوی با61باشد. در غیر این صورت،ValueErrorپرتاب خواهد شد. اگر max_workers برابرNoneباشد، مقدار پیشفرض انتخابشده حداکثر61خواهد بود، حتی اگر پردازندههای بیشتری در دسترس باشند. mp_context میتواند یک زمینهmultiprocessingیاNoneباشد. از آن برای راهاندازی کارگرها استفاده خواهد شد. اگر mp_context برابرNoneباشد یا داده نشود، از زمینه پیشفرضmultiprocessingاستفاده میشود. زمینهها و متدهای شروع را ببینید.initializer یک فراخوانیپذیر اختیاری است که در آغاز هر فرایند کارگر فراخوانی میشود؛ initargs تاپلی از آرگومانهای ارسالشده به initializer است. اگر initializer استثنایی پرتاب کند، تمام کارهای در انتظار فعلی و همچنین هر تلاشی برای ارسال کارهای بیشتر به استخر،
BrokenProcessPoolرا پرتاب خواهند کرد.max_tasks_per_child یک آرگومان اختیاری است که حداکثر تعداد وظایفی را مشخص میکند که یک فرایند واحد میتواند پیش از خروج و جایگزینی با یک فرایند کارگر تازه اجرا کند. بهطور پیشفرض max_tasks_per_child برابر
Noneاست، به این معنا که فرایندهای کارگر تا زمانی که استخر وجود دارد زنده میمانند. هرگاه یک مقدار حداکثری مشخص شود، در نبود پارامتر mp_context، روش شروع چندپردازشی "spawn" بهطور پیشفرض استفاده میشود. این قابلیت با روش شروع "fork" ناسازگار است.تغییر یافته در نسخهی 3.3: هنگامی که یکی از فرایندهای کارگر بهطور ناگهانی خاتمه یابد، اکنون یک خطای
BrokenProcessPoolپرتاب میشود. پیشتر، رفتار تعریفنشده بود، اما عملیاتها روی اجراکننده (executor) یا آیندهنماهای (futures) آن اغلب قفل میشدند یا به بنبست میرسیدند.تغییر یافته در نسخهی 3.7: آرگومان mp_context افزوده شد تا کاربران بتوانند start_method را برای فرایندهای کارگر ایجادشده توسط استخر کنترل کنند.
آرگومانهای initializer و initargs اضافه شدند.
تغییر یافته در نسخهی 3.11: آرگومان max_tasks_per_child افزوده شد تا کاربران بتوانند طول عمر کارگران استخر را کنترل کنند.
تغییر یافته در نسخهی 3.12: در سیستمهای POSIX، اگر برنامه شما چندین نخ دارد و زمینهی
multiprocessingاز روش شروع"fork"استفاده میکند: تابعos.fork()که بهصورت داخلی برای ایجاد کارگرها فراخوانی میشود، ممکن است یکDeprecationWarningپرتاب کند. یک mp_context را که برای استفاده از یک روش شروع متفاوت پیکربندی شده است، ارسال کنید. برای توضیح بیشتر، مستنداتos.fork()را ببینید.تغییر یافته در نسخهی 3.13: max_workers بهطور پیشفرض از
os.process_cpu_count()استفاده میکند، نهos.cpu_count().تغییر یافته در نسخهی 3.14: متد پیشفرض شروع فرایند (به زمینهها و متدهای شروع مراجعه کنید) از fork تغییر کرده است. اگر به متد شروع fork برای
ProcessPoolExecutorنیاز دارید، باید بهصراحتmp_context=multiprocessing.get_context("fork")را ارسال کنید.تغییر یافته در نسخهی 3.14.7: بنبستی (gh-115634) برطرف شد که در آن اجراکننده ممکن بود پس از خروج یک فرایند کارگر در اثر رسیدن به حد max_tasks_per_child، در حالی که وظایفی در صف باقی مانده بودند، معلق بماند.
- terminate_workers()¶
تلاش میکند تا با فراخوانی
Process.terminateروی هر یک از آنها، بلافاصله تمام فرایندهای کارگر زنده را خاتمه دهد. در داخل،Executor.shutdown()را نیز فراخوانی میکند تا اطمینان حاصل شود که تمام منابع دیگر مرتبط با اجراکننده آزاد شدهاند.پس از فراخوانی این متد، فراخواننده دیگر نباید وظایفی را به اجراکننده (executor) ارسال کند.
اضافه شده در نسخهی 3.14.
- kill_workers()¶
تلاش میکند تمام فرآیندهای کارگر زنده را بلافاصله با فراخوانی
Process.killبرای هر یک از آنها از بین ببرد. بهصورت داخلی، همچنینExecutor.shutdown()را نیز فراخوانی میکند تا اطمینان حاصل شود که همه منابع دیگر مرتبط با اجراکننده آزاد میشوند.پس از فراخوانی این متد، فراخواننده دیگر نباید وظایفی را به اجراکننده (executor) ارسال کند.
اضافه شده در نسخهی 3.14.
مثال ProcessPoolExecutor¶
import concurrent.futures
import math
PRIMES = [
112272535095293,
112582705942171,
112272535095293,
115280095190773,
115797848077099,
1099726899285419]
def is_prime(n):
if n < 2:
return False
if n == 2:
return True
if n % 2 == 0:
return False
sqrt_n = int(math.floor(math.sqrt(n)))
for i in range(3, sqrt_n + 1, 2):
if n % i == 0:
return False
return True
def main():
with concurrent.futures.ProcessPoolExecutor() as executor:
for number, prime in zip(PRIMES, executor.map(is_prime, PRIMES)):
print('%d is prime: %s' % (number, prime))
if __name__ == '__main__':
main()
اشیای Future¶
کلاس Future اجرای ناهمگام یک شیء فراخوانیپذیر را در بر میگیرد. نمونههای Future توسط Executor.submit() ایجاد میشوند.
- class concurrent.futures.Future¶
اجرای ناهمگام یک فراخوانیپذیر را کپسوله میکند. نمونههای
FutureتوسطExecutor.submit()ایجاد میشوند و نباید بهصورت مستقیم ایجاد شوند، مگر برای آزمون.- cancel()¶
برای لغو فراخوانی تلاش میکند. اگر فراخوانی در حال اجرا باشد یا اجرای آن به پایان رسیده باشد و نتوان آن را لغو کرد، متد
Falseرا برمیگرداند، در غیر این صورت فراخوانی لغو میشود و متدTrueرا برمیگرداند.
- cancelled()¶
اگر فراخوانی با موفقیت لغو شده باشد،
Trueبرگردانده میشود.
- running()¶
اگر فراخوانی در حال حاضر در حال اجرا باشد و قابل لغو نباشد،
Trueرا برمیگرداند.
- done()¶
اگر فراخوانی با موفقیت لغو شد یا اجرای آن به پایان رسید،
Trueرا برمیگرداند.
- result(timeout=None)¶
مقدار برگرداندهشده از فراخوانی را برمیگرداند. اگر فراخوانی هنوز به پایان نرسیده باشد، این متد حداکثر به مدت timeout ثانیه منتظر میماند. اگر فراخوانی ظرف timeout ثانیه به پایان نرسد، استثنای
TimeoutErrorپرتاب میشود. timeout میتواند int یا float باشد. اگر timeout مشخص نشده باشد یاNoneباشد، محدودیتی برای زمان انتظار وجود ندارد.اگر فیوچر (future) پیش از تکمیل لغو شود،
CancelledErrorپرتاب میشود.اگر فراخوانی استثنایی را پرتاب کرد، این متد همان استثنا را پرتاب خواهد کرد.
- exception(timeout=None)¶
استثنای پرتابشده توسط فراخوانی را بازمیگرداند. اگر فراخوانی هنوز کامل نشده باشد، این متد حداکثر تا timeout ثانیه صبر میکند. اگر فراخوانی ظرف timeout ثانیه کامل نشود، یک
TimeoutErrorپرتاب خواهد شد. timeout میتواند int یا float باشد. اگر timeout مشخص نشده باشد یاNoneباشد، محدودیتی برای زمان انتظار وجود ندارد.اگر فیوچر (future) پیش از تکمیل لغو شود،
CancelledErrorپرتاب میشود.اگر فراخوانی بدون پرتاب استثنا به پایان برسد،
Noneبرگردانده میشود.
- add_done_callback(fn)¶
fn فراخوانیپذیر را به آینده متصل میکند. هنگامی که future لغو شود یا اجرای آن به پایان برسد، fn با future بهعنوان تنها آرگومان خود فراخوانی میشود.
فراخوانیپذیرهای افزودهشده به ترتیبی که افزوده شدهاند فراخوانی میشوند و همیشه در نخی متعلق به فرایندی که آنها را افزوده است فراخوانی میشوند. اگر فراخوانیپذیر زیرکلاسی از
Exceptionرا پرتاب کند، ثبت و نادیده گرفته میشود. اگر فراخوانیپذیر زیرکلاسی ازBaseExceptionرا پرتاب کند، رفتار تعریفنشده است.اگر فیوچر از قبل تکمیل شده یا لغو شده باشد، fn بلافاصله فراخوانی خواهد شد.
متدهای زیر از
Futureبرای استفاده در آزمون واحدها و پیادهسازیهایExecutorدر نظر گرفته شدهاند.- set_running_or_notify_cancel()¶
این متد باید فقط توسط پیادهسازیهای
Executorپیش از اجرای کار مرتبط باFutureو توسط آزمون واحدها فراخوانی شود.اگر متد
Falseرا برگرداند، آنگاهFutureلغو شده است، یعنیFuture.cancel()فراخوانی شده وTrueرا برگردانده است. تمام نخهایی که در انتظار تکمیلFutureهستند (یعنی از طریقas_completed()یاwait()) بیدار خواهند شد.اگر متد
Trueرا برگرداند،Futureلغو نشده و در وضعیت در حال اجرا قرار گرفته است، یعنی فراخوانیهایFuture.running()مقدارTrueرا برمیگردانند.این متد فقط یک بار فراخوانیپذیر است و پس از فراخوانی
Future.set_result()یاFuture.set_exception()نمیتواند فراخوانی شود.
- set_result(result)¶
نتیجهی کار مرتبط با
Futureرا برابر result قرار میدهد.این متد باید فقط توسط پیادهسازیهای
Executorو آزمون واحدها مورد استفاده قرار گیرد.تغییر یافته در نسخهی 3.8: این متد در صورتی که
Futureاز قبل انجام شده باشد،concurrent.futures.InvalidStateErrorرا پرتاب میکند.
- set_exception(exception)¶
نتیجهی کار مرتبط با
Futureرا برابر باExceptionexception قرار میدهد.این متد باید فقط توسط پیادهسازیهای
Executorو آزمون واحدها مورد استفاده قرار گیرد.تغییر یافته در نسخهی 3.8: این متد در صورتی که
Futureاز قبل انجام شده باشد،concurrent.futures.InvalidStateErrorرا پرتاب میکند.
توابع ماژول¶
- concurrent.futures.wait(fs, timeout=None, return_when=ALL_COMPLETED)¶
منتظر بمانید تا نمونههای
Futureدادهشده توسط fs (که ممکن است توسط نمونههای مختلفExecutorایجاد شده باشند) کامل شوند. آیندهنماهای تکراری دادهشده به fs حذف میشوند و تنها یک بار برگردانده خواهند شد. یک تاپل دوتایی نامدار از مجموعهها برمیگرداند. مجموعه اول، کهdoneنام دارد، شامل آیندهنماهایی است که پیش از کامل شدن انتظار، کامل شدهاند (آیندهنماهای تمامشده یا لغوشده). مجموعه دوم، کهnot_doneنام دارد، شامل آیندهنماهایی است که کامل نشدهاند (آیندهنماهای در انتظار یا در حال اجرا).میتوان از timeout برای کنترل حداکثر تعداد ثانیههای انتظار پیش از بازگشت استفاده کرد. timeout میتواند یک int یا float باشد. اگر timeout مشخص نشده باشد یا
Noneباشد، محدودیتی برای زمان انتظار وجود ندارد.return_when مشخص میکند که این تابع چه زمانی باید بازگشت کند. این مقدار باید یکی از ثابتهای زیر باشد:
ثابت
توضیحات
- concurrent.futures.FIRST_COMPLETED¶
تابع زمانی برمیگردد که هر آینده به پایان برسد یا لغو شود.
- concurrent.futures.FIRST_EXCEPTION¶
این تابع هنگامی بازگشت خواهد کرد که هر فیوچری با پرتاب استثنا به پایان برسد. اگر هیچ فیوچری استثنایی پرتاب نکند، معادل
ALL_COMPLETEDاست.- concurrent.futures.ALL_COMPLETED¶
تابع زمانی بازمیگردد که همهی آیندهنماها (futures) به پایان برسند یا لغو شوند.
- concurrent.futures.as_completed(fs, timeout=None)¶
پیمایشگری بر روی نمونههای
Futureدادهشده توسط fs (که ممکن است توسط نمونههای مختلفExecutorایجادشده باشند) برمیگرداند که Futureها را بهمحض کاملشدن (Futureهای تمامشده یا لغوشده) تولید میکند. هر Future دادهشده توسط fs که تکراری باشد، تنها یک بار برگردانده میشود. هر Future که پیش از فراخوانیas_completed()کاملشده باشد، ابتدا تولید میشود. پیمایشگر برگرداندهشده در صورتی یکTimeoutErrorپرتاب میکند که__next__()فراخوانی شود و نتیجه پس از timeout ثانیه از فراخوانی اصلیas_completed()در دسترس نباشد. timeout میتواند یک int یا float باشد. اگر timeout تعییننشده باشد یاNoneباشد، محدودیتی برای زمان انتظار وجود ندارد.
همچنین ملاحظه نمائید
- PEP 3148 -- آیندهنماها (futures) - اجرای محاسبات بهصورت ناهمگام
پیشنهادی که این قابلیت را برای گنجاندن در کتابخانه استاندارد پایتون توصیف میکرد.
کلاسهای استثنا¶
- exception concurrent.futures.CancelledError¶
هنگامی که یک آینده لغو میشود، پرتاب میشود.
- exception concurrent.futures.TimeoutError¶
یک نام مستعار منسوخشده از
TimeoutErrorاست که هنگامی که یک عملیات آتی از مهلت زمانی دادهشده فراتر برود، پرتاب میشود.تغییر یافته در نسخهی 3.11: این کلاس به نام مستعاری برای
TimeoutErrorتبدیل شد.
- exception concurrent.futures.BrokenExecutor¶
این کلاس استثنا که از
RuntimeErrorمشتق شده است، زمانی پرتاب میشود که یک اجراکننده (executor) به دلیلی خراب شده باشد و نتوان از آن برای ارسال یا اجرای وظایف جدید استفاده کرد.اضافه شده در نسخهی 3.7.
- exception concurrent.futures.InvalidStateError¶
زمانی پرتاب میشود که یک عملیات غیرمجاز در وضعیت فعلی روی یک future انجام شود.
اضافه شده در نسخهی 3.8.
- exception concurrent.futures.thread.BrokenThreadPool¶
این کلاس استثنا که از
BrokenExecutorمشتق شده است، زمانی پرتاب میشود که یکی از کارگرهایThreadPoolExecutorدر راهاندازی ناموفق باشد.اضافه شده در نسخهی 3.7.
- exception concurrent.futures.interpreter.BrokenInterpreterPool¶
این کلاس استثنا، مشتق از
BrokenThreadPool، زمانی پرتاب میشود که یکی از کارگرهایInterpreterPoolExecutorدر راهاندازی ناموفق بوده باشد.اضافه شده در نسخهی 3.14.
- exception concurrent.futures.process.BrokenProcessPool¶
این کلاس استثنا از
BrokenExecutor(پیشترRuntimeError) مشتق شده است و زمانی پرتاب میشود که یکی از کارگرهایProcessPoolExecutorبهصورت غیرپاکیزه خاتمه یافته باشد (برای مثال، اگر از بیرون کشته شده باشد).اضافه شده در نسخهی 3.3.