فارسیش میشه قفل مترجم جهانی - Global Interpreter Lock - که یک مکانیزم در CPython (پیادهسازی پیشفرض و پراستفادهترین پایتون) هست که مانع اجرای همزمان بایت کدهای پایتون توسط چندین native thread میشه. برای سادهسازی مدیریت حافظه در حضور برنامههای چند thread ای در پایتون طراحی شده. برای پیادهسازی concurrent programming در پایتون هست.
و GIL فقط به یک thread اجازه اجرای بایتکد پایتون رو در هر زمان در یک پردازش میده. این یعنی اینکه multiple threads در پایتون نمیتونه کد پایتون رو به طور موازی اجرا کنه. (دلیلش اینه که مدیریت حافظه آسونتر بشه، از race condition جلوگیری بشه، تغییرات در کد موجود حداقل بشه و...)
و GIL در مدیریت دسترسی به آبجکتهای پایتون و ساختاردادهها کمک میکنه و از race condition جلوگیری میکنه که ممکنه به دلیل اینکه چندین thread بخوان یک دیتای یکسان رو همزمان تغییر بدن ایجاد میشه.
و GIL در Jython و ironPython وجود نداره.
نمونه کد:
import threading counter = 0 def increment(): global counter for _ in range(1000000): counter += 1 # Create two threads to increment the counter thread1 = threading.Thread(target=increment) thread2 = threading.Thread(target=increment) # Start both threads thread1.start() thread2.start() # Wait for both threads to finish thread1.join() thread2.join() # Expected result: The counter will be less than 2,000,000 due to GIL contention print("Counter:", counter)
در این کد دو thread سعی میکن که یک شمارشگر مشترک رو اضافه کنن. با توجه به GIL، عملیات افزایش اتمی نیست (چون شامل گامهای خوندن، افزودن و نوشتن میشه که ممکنه وسطش thread رو سوییچ کنه) و ممکنه منجر به این بشه که مقدار شمارشگر کمتر از مقدار مورد انتظار ۲ میلیون بشه. با کد زیر میشه عملیات افزایش رو اتومیک کرد: از RLock یا Semaphore هم میشه استفاده کرد.
with counter_lock: # Incrementing the counter within the lock ensures atomicity counter += 1
باید نسبت به محدودیت GIL آگاه بود.
در سناریوهای مرتبط با CPU از مدلهای همزمانی جایگزین مثل multiprocessing در زمانی که همزمانی واقعی نیاز داریم رو در نظر بگیریم.
در سناریوهای مرتبط با I/O، بیایم asynchronous programming رو مدنظر قرار بدیم و از چارچوبهایی مثل asyncio برای همزمانی بدون محدودیتهای GIL استفاده کنیم.
در یکسری از کتابخونهها آزاد کردن GIL در سناریوهای مختلف در نظر گرفته شده تا threadهای دیگه بتونن اجرا بشن. این کتابخونهها رو مدنظر قرار بدین.
و در نهایت اگر موازیسازی براتون حیاتیه، پیادهسازیهای جایگزین پایتون رو مثل Jython و ironPython رو در نظر بگیرین که GIL رو ندارن.