หัวข้อใดที่แบ่งปันกันโดยทั่วไป


20

นี่เป็นคำถามทั่วไป และถ้าใครต้องการทำให้การใช้งานเฉพาะเจาะจงฉันจะชอบสิ่งที่เกี่ยวข้องกับ Unix แต่ก่อนอื่นต้องรู้ปัญหาต่อไปนี้โดยทั่วไป:

ฉันอ่านกระบวนการเดียวสามารถมีหลายเธรด หลายเธรดของกระบวนการเดียวกันจะแบ่งปันสิ่งต่าง ๆ ในหมู่พวกเขา ฉันต้องการที่จะรู้ว่าสิ่งที่พวกเขาแบ่งปันและสิ่งที่ไม่ กระบวนการพิจารณาประกอบด้วยพื้นที่ที่อยู่, สแต็ค, กอง, ตัวแปรทั่วโลก, รหัส, ข้อมูล, ทรัพยากรระบบปฏิบัติการสิ่งที่ในหมู่พวกเขาร่วมกันโดยกระทู้? ฉันมีการคาดเดาต่อไปนี้:

  1. ตัวแปรทั่วโลก -ฉันได้อ่านหัวข้อแบ่งปันตัวแปรทั่วโลก ในขณะที่การเขียนโปรแกรมใน Java และ C # ฉันได้ทำเธรดเพื่อแบ่งปันตัวแปรระดับชั้นเรียน ดังนั้นฉันจึงเชื่อว่าเธรดจะแชร์ตัวแปรทั่วโลก (แต่ไม่แน่ใจว่าแนวคิดในภาษาการเขียนโปรแกรมระดับสูงแปลว่าเป็นข้อเท็จจริงระดับระบบปฏิบัติการต่ำหรือไม่)

  2. ฮีป -เนื่องจากตัวแปรโกลบอลถูกเก็บไว้ในฮีปฮีปจะถูกแชร์ระหว่างเธรด

  3. สแต็ค -เนื่องจากแต่ละเธรดสามารถมีลำดับการเรียกใช้ / โค้ดของตัวเองได้จึงต้องมีสแต็กของตัวเองซึ่งมันอาจจะผลัก / ป๊อปอัพเนื้อหาของโปรแกรมตัวนับ (เมื่อพูดว่าการเรียกใช้ฟังก์ชัน ดังนั้นเธรดของกระบวนการเดียวกันจะไม่แชร์สแต็ก

ตอนนี้ฉันไม่แน่ใจเกี่ยวกับการแบ่งปันสิ่งต่อไปนี้

  1. พื้นที่ที่อยู่ -ไม่แน่ใจว่าสิ่งที่นับว่าอยู่ภายใต้พื้นที่ที่อยู่ แต่ฉันคิดว่าพื้นที่ที่อยู่โดยทั่วไปจะใช้ในบริบทของกระบวนการไม่ใช่เธรด และเนื่องจากเธรดทั้งหมดของกระบวนการเดียวกันอยู่ในพื้นที่แอดเดรสเดียวกันกับกระบวนการพาเรนต์จึงมีการกล่าวว่าเธรดใช้พื้นที่ที่อยู่ร่วมกัน (แต่พวกเขาจะรักษาสแต็คที่แตกต่างกันภายในพื้นที่ที่อยู่เดียวกันได้หรือไม่)

  2. ทรัพยากรระบบปฏิบัติการ -ฉันคิดว่านี่อาจเป็นการใช้งานเฉพาะอย่างยิ่ง ตัวอย่างเช่นกระบวนการหลักสามารถเลือกให้การจัดการไฟล์เดียวกันกับบางส่วนของเธรดและไม่ให้ทั้งหมด หรือฉันเข้าใจผิดและทรัพยากรระบบปฏิบัติการหมายถึงอย่างอื่นที่ไม่ใช่ไฟล์?

  3. รหัส -เธรดสามารถมีรหัสที่แตกต่างกันได้ดังนั้นรหัสที่ใช้ร่วมกันอาจไม่เป็นเช่นนั้นเสมอไป

  4. ข้อมูล -ไม่แน่ใจเกี่ยวกับสิ่งที่ต้องพิจารณาภายใต้ข้อมูล แต่ต้องแน่ใจว่ามีการแชร์ตัวแปรส่วนกลางระหว่างเธรด และตรวจสอบว่าตัวแปรท้องถิ่นนั้นไม่ได้ถูกแชร์ในลักษณะเดียวกัน

โดยรวมแล้วฉันสับสนอย่างมากเนื่องจากศัพท์ที่คลุมเครือการสรุปทั่วไปที่ทำได้ในหนังสือระบบปฏิบัติการและรายละเอียดเฉพาะของการติดตั้งเพิ่มเติมที่ให้ไว้ทางออนไลน์ ดังนั้นฉันจึงพยายามหาคำตอบที่สามารถทำให้ฉันพึงพอใจ

คำตอบ:


13

โดยทั่วไปแต่ละเธรดมีการลงทะเบียนของตัวเอง (รวมถึงตัวนับโปรแกรมของตัวเอง) ตัวชี้สแต็กของตัวเองและสแต็กของตัวเอง ทุกอย่างอื่นถูกแชร์ระหว่างเธรดที่แชร์โปรเซส

โดยเฉพาะอย่างยิ่งกระบวนการโดยทั่วไปถือว่าประกอบด้วยชุดของหัวข้อการแบ่งปันพื้นที่ที่อยู่กองข้อมูลแบบคงที่และกลุ่มรหัสและอธิบายไฟล์*

พื้นที่ที่อยู่เป็นเพียงการทำแผนที่ของที่อยู่ตรรกะเป็นชิ้นที่เฉพาะเจาะจงของหน่วยความจำกายภาพ ดังนั้นเมื่อเราพูดว่าเธรดทั้งหมดในกระบวนการแชร์พื้นที่ที่อยู่เดียวกันเราหมายความว่าเมื่อเข้าถึงตัวแปรfooในขอบเขตส่วนกลางเธรดทั้งหมดจะเห็นตัวแปรเดียวกัน ในทำนองเดียวกันเธรดทั้งหมดอาจใช้จุดที่แตกต่างกันในรหัสในเวลาใดก็ได้ แต่พวกเขาทั้งหมดได้รับอนุญาตให้เรียกใช้ฟังก์ชันสากลbar()ซึ่งจะสอดคล้องกับฟังก์ชั่นเดียวกันสำหรับทุกเธรดในกระบวนการ

ระบบปฏิบัติการที่ทันสมัยส่วนใหญ่ได้เพิ่มแนวคิดของการจัดเก็บภายในเธรดซึ่งเป็นตัวแปรของขอบเขตทั่วโลกที่ไม่ได้ใช้ร่วมกัน errnoตัวอย่างปกติของการใช้นี้เป็นตัวแปร นั่นเป็นตัวแปรเดียวของขอบเขตทั่วโลก แต่ในระบบปฏิบัติการที่ทันสมัยส่วนใหญ่แต่ละเธรดจะได้รับสำเนาภายในเครื่องของตนเองดังนั้นข้อผิดพลาดในการเรียกไลบรารีบนเธรดหนึ่งจะไม่ส่งผลกระทบต่อพฤติกรรมของเธรดอื่น

*มีบางสถานะกระบวนการเพิ่มเติมที่แบ่งใช้โดยเธรดทั้งหมดในกระบวนการสิ่งต่าง ๆ เช่น id กระบวนการการจัดการสัญญาณและการล็อกไฟล์ สำหรับรายการทั้งหมดของสถานะกระบวนการที่แบ่งใช้โดยเธรดคุณต้องดูเอกสารประกอบสำหรับการใช้เธรดเฉพาะ ยกตัวอย่างเช่นpthreads หน้าคน


4

หัวข้อขึ้นมาในสองมุมมอง: ระบบปฏิบัติการและภาษาการเขียนโปรแกรม ในทั้งสองกรณีมีการเปลี่ยนแปลงในคุณลักษณะที่เธรดมีอยู่

คำจำกัดความที่น้อยที่สุดของเธรดคือมันเป็นสิ่งที่เกิดขึ้นตามลำดับสิ่งหนึ่งต่อจากกัน

ในโมเดลการดำเนินการของเครื่องทั่วไปแต่ละเธรดมีชุดรีจิสเตอร์วัตถุประสงค์ทั่วไปและตัวนับโปรแกรมของตนเอง หากเครื่องกำหนดการลงทะเบียนที่เฉพาะเจาะจงเป็นตัวชี้สแต็กจะมีหนึ่งสำเนาต่อเธรด

จากมุมมองของระบบปฏิบัติการขั้นต่ำที่ระบบปฏิบัติการต้องการเพื่อสนับสนุนเธรดคือวิธีการสลับระหว่างเธรด สิ่งนี้สามารถเกิดขึ้นได้โดยอัตโนมัติ ( มัลติทาสกิ้งแบบ preptiveหรือเฉพาะเมื่อเธรดทำการร้องขออย่างชัดเจน (แบบมัลติทาสก์แบบร่วมมือในบางครั้งเธรดนั้นเรียกว่าเส้นใย ) นอกจากนี้ยังมีโมเดลไฮบริดที่มีทั้งการจองล่วงหน้าและอัตราผลตอบแทนแบบร่วมมือ หรืองาน แต่ให้ผลตอบแทนที่ชัดเจนระหว่างกลุ่มของกลุ่ม / งานเดียวกันการสลับไปมาระหว่างเธรดเกี่ยวข้องกับการบันทึกค่ารีจิสเตอร์ของเธรดเก่าอย่างน้อยที่สุดและเรียกคืนค่ารีจิสเตอร์ของเธรดใหม่

ในระบบปฏิบัติการมัลติทาสกิ้งที่มีการแยกระหว่างงาน (หรือกระบวนการคุณสามารถปฏิบัติตามเงื่อนไขเหล่านี้เป็นคำพ้องความหมายในบริบทของระบบปฏิบัติการ) แต่ละงานมีทรัพยากรของตัวเองในพื้นที่ที่อยู่เฉพาะ แต่ยังเปิดไฟล์สิทธิ์ ฯลฯ แยกได้ ที่ให้ไว้โดยเคอร์เนลระบบปฏิบัติการเอนทิตีที่อยู่เหนือกระบวนการ โดยปกติแล้วงานแต่ละงานจะมีเธรดอย่างน้อยหนึ่งเธรด - งานที่ไม่ได้เรียกใช้โค้ดไม่ได้ใช้งานบ่อยนัก ระบบปฏิบัติการอาจรองรับหรือไม่รองรับหลายเธรดในงานเดียวกัน เช่น Unix ดั้งเดิมไม่ได้ งานยังคงสามารถรันหลายเธรดได้โดยจัดเรียงเพื่อสลับระหว่างเธรด - ซึ่งไม่ต้องการสิทธิ์พิเศษใด ๆ สิ่งนี้เรียกว่า“ เธรดผู้ใช้” โดยเฉพาะอย่างยิ่งในบริบท Unix ทุกวันนี้ระบบ Unix ส่วนใหญ่มีการจัดเตรียมเคอร์เนลเธรดโดยเฉพาะอย่างยิ่งเนื่องจากเป็นวิธีเดียวที่จะมีเธรดจำนวนมากของกระบวนการเดียวกันที่ทำงานบนโปรเซสเซอร์ที่แตกต่างกัน

ทรัพยากรระบบปฏิบัติการส่วนใหญ่นอกเหนือจากเวลาการคำนวณจะเชื่อมต่อกับงานไม่ใช่เธรด ระบบปฏิบัติการบางระบบ (ตัวอย่างเช่น Linux) คั่นขอบเขตสแต็กอย่างชัดเจนซึ่งในกรณีนี้แต่ละเธรดมีของตนเอง แต่มีระบบปฏิบัติการที่เคอร์เนลไม่ทราบอะไรเกี่ยวกับสแต็กพวกเขาเป็นเพียงส่วนหนึ่งของฮีปเท่าที่เกี่ยวข้อง เคอร์เนลยังจัดการบริบทเคอร์เนลสำหรับแต่ละเธรดซึ่งเป็นโครงสร้างข้อมูลที่มีข้อมูลเกี่ยวกับสิ่งที่เธรดกำลังทำอยู่ สิ่งนี้ทำให้เคอร์เนลจัดการหลายเธรดที่ถูกบล็อกในการเรียกระบบในเวลาเดียวกัน

เท่าที่ระบบปฏิบัติการมีความเกี่ยวข้องเธรดของงานจะเรียกใช้รหัสเดียวกัน แต่อยู่ในตำแหน่งที่แตกต่างกันในรหัสนั้น (ค่าตัวนับโปรแกรมที่แตกต่างกัน) อาจเกิดขึ้นหรือไม่เกิดขึ้นได้ว่าบางส่วนของรหัสของโปรแกรมนั้นจะถูกดำเนินการในเธรดเฉพาะเสมอ แต่โดยทั่วไปจะมีรหัสทั่วไป (เช่นฟังก์ชั่นยูทิลิตี้) ที่สามารถเรียกได้จากเธรดใด ๆ กระทู้ทั้งหมดเห็นข้อมูลเดียวกันมิฉะนั้นพวกเขาจะถือว่าเป็นงานที่แตกต่างกัน ถ้าข้อมูลบางอย่างสามารถเข้าถึงได้โดยเธรดเฉพาะนั่นคือโดยทั่วไปแล้วขอบเขตของภาษาการเขียนโปรแกรมไม่ใช่ของระบบปฏิบัติการ

ในภาษาโปรแกรมส่วนใหญ่พื้นที่เก็บข้อมูลจะถูกแชร์ระหว่างเธรดของโปรแกรมเดียวกัน นี่เป็นโมเดลหน่วยความจำแบบแบ่งใช้ของการเขียนโปรแกรมพร้อมกัน เป็นที่นิยมมาก แต่ก็มีข้อผิดพลาดได้ง่ายเช่นกันเนื่องจากโปรแกรมเมอร์จำเป็นต้องระมัดระวังเมื่อสามารถเข้าถึงข้อมูลเดียวกันหลายเธรดได้เนื่องจากเงื่อนไขการแข่งขันอาจเกิดขึ้นได้ โปรดทราบว่าแม้กระทั่งตัวแปรท้องถิ่นสามารถแชร์ระหว่างเธรด:“ ตัวแปรท้องถิ่น” (ปกติแล้ว) หมายถึงตัวแปรที่ชื่อมีความถูกต้องเฉพาะในระหว่างการดำเนินการฟังก์ชั่นหนึ่งครั้ง แต่เธรดอื่นสามารถรับตัวชี้ไปยังตัวแปรนั้นและเข้าถึงได้

นอกจากนี้ยังมีภาษาการเขียนโปรแกรมที่แต่ละเธรดมีที่เก็บข้อมูลของตนเองและการสื่อสารระหว่างกันเกิดขึ้นโดยการส่งข้อความผ่านช่องทางการสื่อสาร นี่คือรูปแบบการส่งข้อความของการเขียนโปรแกรมพร้อมกัน Erlangเป็นภาษาโปรแกรมหลักที่เน้นการส่งข้อความ สภาพแวดล้อมการประมวลผลมีการจัดการเธรดที่มีน้ำหนักเบามากและสนับสนุนโปรแกรมที่เขียนด้วยเธรดอายุสั้นจำนวนมากตรงกันข้ามกับภาษาการเขียนโปรแกรมอื่น ๆ ส่วนใหญ่ที่การสร้างเธรดเป็นการดำเนินการที่ค่อนข้างแพงและสภาพแวดล้อมรันไทม์ไม่สามารถรองรับขนาดใหญ่มาก จำนวนเธรดในเวลาเดียวกัน ส่วนย่อยของ Erlang (ส่วนหนึ่งของภาษาที่เกิดขึ้นภายในเธรดโดยเฉพาะการจัดการข้อมูล) คือ (ส่วนใหญ่) ทำงานได้อย่างหมดจด ดังนั้นเธรดสามารถส่งข้อความไปยังเธรดอื่นที่มีข้อมูลบางส่วนและไม่จำเป็นต้องกังวลเกี่ยวกับข้อมูลที่ถูกแก้ไขโดยเธรดอื่นในขณะที่กำลังใช้งานอยู่

บางภาษาผสมผสานทั้งสองรุ่นโดยนำเสนอที่เก็บข้อมูลเธรดโลคัลโดยมีหรือไม่มีระบบพิมพ์เพื่อแยกแยะที่เก็บของเธรดโลคัลจากที่เก็บโกลบอล หน่วยเก็บข้อมูลเธรดโลคัลเป็นคุณลักษณะความสะดวกสบายที่อนุญาตให้ชื่อตัวแปรกำหนดตำแหน่งหน่วยเก็บข้อมูลที่แตกต่างกันในเธรดที่แตกต่างกัน

การติดตามบางส่วน (ยาก) ที่อาจเป็นที่สนใจที่จะเข้าใจว่าเธรดคืออะไร:

  • ขั้นต่ำที่เคอร์เนลต้องทำเพื่อสนับสนุนหลายเธรดคืออะไร?
  • ในสภาพแวดล้อมแบบมัลติโปรเซสเซอร์สิ่งที่ต้องใช้ในการโยกย้ายเธรดจากตัวประมวลผลหนึ่งไปยังตัวประมวลผลอื่นได้อย่างไร
  • สิ่งที่ต้องใช้ในการใช้ multithreading แบบร่วมมือ ( coroutines ) ในภาษาการเขียนโปรแกรมที่คุณชื่นชอบโดยไม่มีการสนับสนุนจากระบบปฏิบัติการและไม่ใช้การสนับสนุนในตัวถ้ามี (ระวังว่าภาษาการเขียนโปรแกรมส่วนใหญ่ไม่มีภาษาดั้งเดิมที่จำเป็นในการติดตั้ง coroutines ภายในเธรดเดี่ยว)
  • ภาษาการเขียนโปรแกรมอาจมีลักษณะเป็นอย่างไรหากมีการทำงานพร้อมกัน แต่ไม่มีแนวคิด (ชัดเจน) ของเธรด (ตัวอย่างที่สำคัญ: pi-แคลคูลัส )

นี่คือสิ่งที่น่าสนใจที่สุดที่ฉันได้อ่านในหลายเดือน
JSON

2

ขึ้นอยู่กับว่า หากคุณพิจารณาเธรดตามที่กำหนดไว้เช่นโดย POSIX (และนำเสนอโดยระบบ Unix) หรือโดย Windows (ไม่คุ้นเคยในภายหลังคุณจะต้องถามเฉพาะ) ดังนั้นนั่นจะให้คำตอบของคุณ (ตามที่ @WanderingLogic Linux มีแนวคิดเกี่ยวกับเธรดของตัวเองโดยใช้การclone(2)เรียกระบบที่ไม่ได้มาตรฐาน มันมีการควบคุมที่ค่อนข้างละเอียดของสิ่งที่ผู้ปกครองและเด็กแบ่งปัน มันไปไกลเท่าที่มีfork(2)และvfork(2)เป็นหลักล้อมรอบภายในclone(2)เรียกมันด้วยธงที่เฉพาะเจาะจงเช่นคุณสามารถสร้าง "กระทู้" ที่ใช้ร่วมกันถัดจากอะไรกับผู้ปกครอง เงยหน้าขึ้นมองหน้าคู่มือสำหรับรายละเอียดที่พวกเขามีอยู่เช่นในบรรทัดที่นี่ ใช่ลีนุกซ์นำเสนอสไตล์เธรด POSIX แต่มีอะไรมากกว่านั้น


0

แบ่งปันหัวข้อ:

  • พื้นที่ที่อยู่
  • กอง
  • ข้อมูลคงที่
  • ส่วนรหัส
  • อธิบายไฟล์
  • ตัวแปรทั่วโลก
  • กระบวนการลูก
  • สัญญาณเตือนที่รอดำเนินการ
  • ตัวจัดการสัญญาณและสัญญาณ
  • ข้อมูลการบัญชี

หัวข้อมีของตัวเอง:

  • โปรแกรมนับ
  • ลงทะเบียน
  • ซ้อนกัน
  • สถานะ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.