ฟังก์ชัน Global Interpreter Lock ของ Python คืออะไร? ภาษาอื่น ๆ ที่คอมไพล์เป็น bytecode ใช้กลไกที่คล้ายกันหรือไม่?
ฟังก์ชัน Global Interpreter Lock ของ Python คืออะไร? ภาษาอื่น ๆ ที่คอมไพล์เป็น bytecode ใช้กลไกที่คล้ายกันหรือไม่?
คำตอบ:
โดยทั่วไปสำหรับปัญหาด้านความปลอดภัยของเธรดใด ๆ คุณจะต้องปกป้องโครงสร้างข้อมูลภายในของคุณด้วยการล็อก ซึ่งสามารถทำได้ด้วยความละเอียดระดับต่างๆ
คุณสามารถใช้การล็อกแบบละเอียดซึ่งโครงสร้างที่แยกจากกันทุกชิ้นจะมีการล็อกของตัวเอง
คุณสามารถใช้การล็อกแบบหยาบโดยที่ล็อคเดียวจะปกป้องทุกอย่าง (แนวทาง GIL)
มีข้อดีข้อเสียของแต่ละวิธี การล็อกแบบละเอียดช่วยให้เกิดการขนานกันมากขึ้น - เธรดสองเธรดสามารถดำเนินการควบคู่กันได้เมื่อไม่ได้ใช้ทรัพยากรร่วมกัน อย่างไรก็ตามมีค่าใช้จ่ายในการบริหารที่ใหญ่กว่ามาก สำหรับโค้ดทุกบรรทัดคุณอาจต้องได้รับและปลดล็อคหลาย ๆ ตัว
วิธีการที่เป็นเม็ดหยาบนั้นตรงกันข้าม เธรดสองเธรดไม่สามารถทำงานพร้อมกันได้ แต่เธรดแต่ละเธรดจะทำงานได้เร็วขึ้นเนื่องจากไม่ได้ทำบัญชีมากนัก ท้ายที่สุดแล้วมันจะลดลงระหว่างความเร็วเธรดเดียวและความขนาน
มีความพยายามสองสามครั้งที่จะลบ GIL ใน python แต่ค่าใช้จ่ายพิเศษสำหรับเครื่องเธรดเดี่ยวมักมีขนาดใหญ่เกินไป บางกรณีอาจทำงานช้าลงแม้ในเครื่องที่มีโปรเซสเซอร์หลายตัวเนื่องจากปัญหาการล็อก
ภาษาอื่น ๆ ที่คอมไพล์เป็น bytecode ใช้กลไกที่คล้ายกันหรือไม่?
มันแตกต่างกันไปและอาจไม่ถือว่าเป็นคุณสมบัติของภาษามากเท่ากับคุณสมบัติการนำไปใช้งาน ตัวอย่างเช่นมีการใช้งาน Python เช่น Jython และ IronPython ซึ่งใช้วิธีการเธรดของ VM ที่เป็นพื้นฐานแทนที่จะใช้วิธี GIL นอกจากนี้เวอร์ชันถัดไปของ Ruby ดูเหมือนจะมุ่งสู่การแนะนำ GIL
ต่อไปนี้มาจากคู่มืออ้างอิง Python / C API อย่างเป็นทางการ :
ล่าม Python ไม่ปลอดภัยเธรดอย่างสมบูรณ์ ในการรองรับโปรแกรม Python แบบหลายเธรดมีการล็อกส่วนกลางที่เธรดปัจจุบันต้องยึดไว้ก่อนจึงจะสามารถเข้าถึงวัตถุ Python ได้อย่างปลอดภัย หากไม่มีการล็อกแม้แต่การดำเนินการที่ง่ายที่สุดก็อาจทำให้เกิดปัญหาในโปรแกรมแบบมัลติเธรดได้เช่นเมื่อเธรดสองเธรดเพิ่มจำนวนการอ้างอิงของอ็อบเจ็กต์เดียวกันพร้อมกันจำนวนอ้างอิงอาจเพิ่มขึ้นเพียงครั้งเดียวแทนที่จะเป็นสองครั้ง
ดังนั้นกฎจึงมีอยู่เฉพาะเธรดที่ได้รับการล็อกตัวแปลส่วนกลางเท่านั้นที่สามารถทำงานบนวัตถุ Python หรือเรียกฟังก์ชัน Python / C API เพื่อให้รองรับโปรแกรม Python แบบหลายเธรดล่ามจะปล่อยและรับการล็อกเป็นประจำโดยค่าเริ่มต้นคำแนะนำทุกๆ 100 ไบต์โค้ด (สามารถเปลี่ยนแปลงได้ด้วย sys.setcheckinterval ()) นอกจากนี้ล็อกยังถูกปลดล็อกและได้รับการร้องขออีกครั้งสำหรับการดำเนินการ I / O ที่อาจบล็อกเช่นการอ่านหรือเขียนไฟล์เพื่อให้เธรดอื่น ๆ สามารถทำงานได้ในขณะที่เธรดที่ร้องขอ I / O กำลังรอให้การดำเนินการ I / O เสร็จสมบูรณ์
ฉันคิดว่ามันสรุปประเด็นได้ดีทีเดียว
ล็อคล่ามทั่วโลกเป็นล็อคประเภท mutex ขนาดใหญ่ที่ป้องกันตัวนับอ้างอิงจากการถูก hosed หากคุณกำลังเขียนโค้ด python ล้วน ๆ ทั้งหมดนี้จะเกิดขึ้นเบื้องหลัง แต่ถ้าคุณฝัง Python ลงใน C คุณอาจต้องถอด / ปลดล็อคอย่างชัดเจน
กลไกนี้ไม่เกี่ยวข้องกับ Python ที่คอมไพล์เป็น bytecode ไม่จำเป็นสำหรับ Java อันที่จริงมันไม่จำเป็นสำหรับJython (ไพ ธ อนคอมไพล์เป็น jvm)
Python เช่น perl 5 ไม่ได้ออกแบบมาตั้งแต่ต้นเพื่อให้ปลอดภัยต่อเธรด เธรดได้รับการต่อกิ่งตามความเป็นจริงดังนั้นการล็อกล่ามส่วนกลางจึงถูกใช้เพื่อรักษาการยกเว้นซึ่งกันและกันซึ่งมีเพียงเธรดเดียวเท่านั้นที่เรียกใช้รหัสในช่วงเวลาที่กำหนดในลำไส้ของล่าม
เธรด Python แต่ละเธรดมีการทำงานหลายอย่างพร้อมกันโดยตัวล่ามโดยการหมุนล็อคทุก ๆ ครั้ง
จำเป็นต้องจับล็อคด้วยตัวคุณเองเมื่อคุณกำลังคุยกับ Python จาก C เมื่อเธรด Python อื่นเปิดใช้งานเพื่อ 'เลือกใช้' โปรโตคอลนี้และตรวจสอบให้แน่ใจว่าไม่มีสิ่งใดที่ไม่ปลอดภัยเกิดขึ้นด้านหลังของคุณ
ระบบอื่น ๆ ที่มีมรดกแบบเธรดเดียวซึ่งพัฒนาต่อมาเป็นระบบมัลลิเธรดมักจะมีกลไกบางอย่างในลักษณะนี้ ตัวอย่างเช่นเคอร์เนล Linux มี "Big Kernel Lock" ตั้งแต่ช่วง SMP แรก ๆ เมื่อเวลาผ่านไปเรื่อย ๆ เนื่องจากประสิทธิภาพการทำงานแบบมัลติเธรดกลายเป็นปัญหาจึงมีแนวโน้มที่จะพยายามแบ่งการล็อกประเภทนี้ออกเป็นชิ้นเล็ก ๆ หรือแทนที่ด้วยอัลกอริธึมและโครงสร้างข้อมูลที่ไม่ต้องล็อกซึ่งเป็นไปได้เพื่อเพิ่มปริมาณงานสูงสุด
reiserfs
- เหตุผลเดียวที่แท้จริงที่ฉันรู้เกี่ยวกับเรื่องนี้)
สำหรับคำถามที่สองของคุณไม่ใช่ภาษาสคริปต์ทั้งหมดที่ใช้สิ่งนี้ แต่จะทำให้มีประสิทธิภาพน้อยลงเท่านั้น ตัวอย่างเช่นเธรดใน Ruby จะเป็นสีเขียวและไม่ใช่แบบเนทีฟ
ใน Python เธรดเป็นแบบเนทีฟและ GIL จะป้องกันไม่ให้ทำงานบนคอร์ที่ต่างกัน
ใน Perl เธรดจะยิ่งแย่ลง พวกเขาเพียงแค่คัดลอกล่ามทั้งหมดและยังห่างไกลจากการใช้งานเหมือนใน Python
บางทีนี้บทความโดย BDFL จะช่วยให้