پاسخ تمرین ۱
این شمارنده نشان میدهد چند Task هنوز اجازهی ورود همزمان دارند. acquire کردن یک واحد از شمارنده کم میکند، و release کردن یک واحد به آن برمیگرداند. وقتی شمارنده به صفر برسد، هر Task جدیدی که بخواهد acquire کند باید منتظر بماند تا یکی از Taskهای قبلی release کند.
پاسخ تمرین ۲
با اینکه همهی Taskها با هم ساخته و شروع شدهاند، Semaphore فقط به اندازهی مقدار اولیهاش اجازهی عبور میدهد. بقیهی Taskها همانجا روی نقطهی acquire منتظر میمانند تا یکی از Taskهای در حال اجرا کارش تمام شود و semaphore را آزاد کند.
پاسخ تمرین ۳
با async with، هم acquire کردن و هم release کردن بهصورت خودکار اطراف بلوک انجام میشود، حتی اگر داخل بلوک خطایی پیش بیاید. اما در روش دستی، خودمان باید این کار را داخل try و finally بپیچیم، وگرنه اگر قبل از رسیدن به خط release خطایی رخ دهد، آن تصاحب ممکن است برای همیشه باز بماند.
پاسخ تمرین ۴
BoundedSemaphore در حالت عادی دقیقا مثل Semaphore عمل میکند، اما یک بررسی امنیتی اضافه دارد: اگر release بیشتر از تعداد دفعاتی که acquire صدا زده شده فراخوانی شود، بهجای اینکه بیصدا اجازه دهد شمارنده از حد طبیعیش بیشتر شود، خطای ValueError را پرتاب میکند. همین ویژگی پیدا کردن باگی که در آن release اشتباها چند بار اضافه صدا زده شده را راحتتر میکند.