หากเธรดใช้ PID เดียวกันจะระบุได้อย่างไร


101

ฉันมีคำถามเกี่ยวกับการใช้เธรดใน Linux

Linux ไม่มีการสนับสนุนเธรดที่ชัดเจน ใน userspace เราอาจใช้เธรดไลบรารี (เช่น NPTL) สำหรับการสร้างเธรด ตอนนี้ถ้าเราใช้ NPTL จะรองรับการทำแผนที่ 1: 1

เคอร์เนลจะใช้clone()ฟังก์ชันเพื่อใช้เธรด

สมมติว่าฉันสร้าง 4 เธรด จากนั้นก็หมายความว่า:

  • จะมี 4 task_struct.
  • ภายในจะมีการจัดหาทรัพยากรที่ใช้ร่วมกันตามข้อโต้แย้งในการโคลนtask_struct(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND)

ตอนนี้ฉันมีคำถามต่อไปนี้:

  1. 4 เธรดจะมี PID เดียวกันหรือไม่? หากมีใครสามารถอธิบายได้อย่างละเอียดจะมีการแบ่งปัน PID อย่างไร
  2. มีการระบุเธรดต่างๆอย่างไร มีแนวคิด TID (thread ID) บ้างไหม

คำตอบ:


280

เธรดทั้งสี่จะมี PID เหมือนกัน แต่เมื่อดูจากด้านบนเท่านั้น สิ่งที่คุณ (ในฐานะผู้ใช้) เรียก PID ไม่ใช่สิ่งที่เคอร์เนล (มองจากด้านล่าง) เรียกว่า PID

ในเคอร์เนลแต่ละเธรดจะมี ID ของตัวเองเรียกว่า PID (แม้ว่ามันจะสมเหตุสมผลกว่าที่จะเรียกสิ่งนี้ว่า TID หรือเธรด ID) และยังมี TGID (ID กลุ่มเธรด) ซึ่งเป็น PID ของเธรด ที่เริ่มกระบวนการทั้งหมด

ในทางที่ง่ายเมื่อสร้างกระบวนการใหม่จะปรากฏเป็นเธรดโดยที่ทั้ง PID และ TGID เป็นหมายเลขเดียวกัน (ใหม่)

เมื่อเธรดเริ่มต้นเธรดอื่นเธรดที่เริ่มต้นนั้นจะได้รับ PID ของตัวเอง (ดังนั้นตัวกำหนดตารางเวลาสามารถกำหนดเวลาได้อย่างอิสระ) แต่จะรับช่วง TGID จากเธรดเดิม

ด้วยวิธีนี้เคอร์เนลสามารถกำหนดเวลาเธรดได้อย่างมีความสุขโดยไม่ขึ้นอยู่กับกระบวนการที่เป็นของพวกเขาในขณะที่กระบวนการ (ID กลุ่มเธรด) จะรายงานให้คุณทราบ

ลำดับชั้นของเธรดต่อไปนี้อาจช่วยได้(a) :

                      USER VIEW
 <-- PID 43 --> <----------------- PID 42 ----------------->
                     +---------+
                     | process |
                    _| pid=42  |_
                  _/ | tgid=42 | \_ (new thread) _
       _ (fork) _/   +---------+                  \
      /                                        +---------+
+---------+                                    | process |
| process |                                    | pid=44  |
| pid=43  |                                    | tgid=42 |
| tgid=43 |                                    +---------+
+---------+
 <-- PID 43 --> <--------- PID 42 --------> <--- PID 44 --->
                     KERNEL VIEW

คุณจะเห็นได้ว่าการเริ่มต้นกระบวนการใหม่(ทางด้านซ้าย) จะทำให้คุณมี PID ใหม่และ TGID ใหม่ (ทั้งสองตั้งค่าเป็นค่าเดียวกัน) ในขณะที่เริ่มเธรดใหม่(ทางด้านขวา) จะให้ PID ใหม่แก่คุณในขณะที่ยังคงเหมือนเดิม TGID เป็นเธรดที่เริ่มต้น


(ก) สั่นกลัวด้วยทักษะกราฟิกที่น่าประทับใจของฉัน :-)


20
FYI getpid()ส่งคืน tgid: asmlinkage long sys_getpid(void) { return current->tgid;}ตามที่แสดงในwww.makelinux.com/
Duke

6
@ ดุ๊ก - ว้าวเลยหาgettgid(2)ฟังก์ชั่นไม่เจอ และgetpid()จะไม่ส่งคืน TID ("PID" ของเธรด) และมีที่gettid(2)มาด้วยวิธีนี้ฉันสามารถบอกได้ว่าเราอยู่ในเธรดหลักหรือไม่
Tomasz Gandor

2
สิ่งนี้นำไปสู่ประเด็นที่น่าสนใจอีกประการหนึ่ง: ดังนั้นหากเธรดและกระบวนการได้รับการจัดการอย่างเท่าเทียมกันภายในเคอร์เนล (นอกเหนือจาก tgid) กระบวนการแบบมัลติเธรดจะได้รับเวลา CPU มากกว่าเธรดเดียวโดยมีเงื่อนไขว่าทั้งสองมีเหมือนกัน ลำดับความสำคัญและไม่มีเธรดใดหยุดชะงักไม่ว่าด้วยเหตุผลใด ๆ (เช่นรอ mutex)
Aconcagua

1
@Aconcagua, CFS (ตัวกำหนดตารางเวลาที่ยุติธรรมอย่างสมบูรณ์ใน Linux) โดยทั่วไปจะทำงานในลักษณะนั้น แต่ยังอนุญาตให้ใช้ส่วนขยายตัวกำหนดตารางเวลากลุ่มเพื่อให้การทำงานที่เป็นธรรมในบางกลุ่มของงานมากกว่างานแต่ละงาน ฉันไม่เคยมองมันอย่างอื่นนอกจากแวบเดียวเท่านั้น
paxdiablo

'' getpgrp '' เพื่อรับรหัสกลุ่ม
Pengcheng

2

เธรดถูกระบุโดยใช้ PIDs และ TGID (Thread group id) พวกเขายังรู้ด้วยว่าเธรดใดเป็นพาเรนต์ของใครโดยพื้นฐานแล้วกระบวนการจะแชร์ PID กับเธรดใด ๆ ที่เริ่มต้น โดยทั่วไปแล้ว ID เธรดจะถูกจัดการโดยไลบรารีเธรดเอง (เช่น pthread ฯลฯ ... ) หากเธรด 4 เธรดเริ่มต้นขึ้นควรมี PID เดียวกัน เคอร์เนลเองจะจัดการกับการตั้งเวลาเธรด แต่ไลบรารีคือสิ่งที่จะจัดการเธรด (ไม่ว่าจะรันได้หรือไม่ขึ้นอยู่กับการใช้วิธีการรวมเธรดและการรอ)

หมายเหตุ: นี่มาจากความทรงจำของเคอร์เนล 2.6.36 งานของฉันในเวอร์ชันเคอร์เนลปัจจุบันอยู่ในเลเยอร์ I / O ดังนั้นฉันจึงไม่รู้ว่าตั้งแต่นั้นมามีการเปลี่ยนแปลงหรือไม่


นี่คือคำอธิบายสำหรับ Linux 2.4 ที่คุณอาจพบunix.stackexchange.com/a/364663/387462
sindhu_sp

-6

Linux จัดเตรียมการfork()เรียกระบบด้วยฟังก์ชันการทำงานดั้งเดิมของการทำซ้ำกระบวนการ Linux ยังให้ความสามารถในการสร้างเธรดโดยใช้การclone()เรียกระบบอย่างไรก็ตาม linux ไม่ได้แยกความแตกต่างระหว่างกระบวนการและเธรด

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