กระบวนการเทียบกับ (เธรด)


9

โดยทั่วไปแล้วแอปพลิเคชัน Linux จะแยก exec (ด้วย execve ()) แต่แอปพลิเคชัน Java และ Apache MPM บางตัวใช้เธรด หากการฟอร์กใช้ fork + exec เพื่อวางไข่กระบวนการเวอร์ชันขั้นสูงสำหรับเธรดคืออะไร JVM หรือ Worker MPM มีเธรดอย่างไร


2
ตรวจสอบ Stackoverflow มีคำถามและคำตอบหลายข้อที่อธิบายส่วนนี้
Henk Langeveld

คำตอบ:


13

แนวคิดเบื้องหลังเธรดและกระบวนการต่างกัน: คุณแยกเส้นทางการดำเนินการ มิฉะนั้นเธรดและกระบวนการต่างกันในสิ่งต่าง ๆ เช่นหน่วยความจำ กระบวนการ Ie มีพื้นที่ VM ที่แตกต่างกันในขณะที่เธรดจะแบ่งปันสิ่งที่มีอยู่ก่อนการแยก

การทำงานทั้งเธรดและการฟอร์กโดยใช้การโทรแบบโคลน () (ชาย 2 แบบ)

แตกต่างจาก fork (2), clone () อนุญาตให้กระบวนการ child แบ่งส่วนของบริบทการดำเนินการกับกระบวนการที่เรียกเช่นพื้นที่หน่วยความจำ, ตารางของ file descriptors, และตารางของตัวจัดการสัญญาณ (โปรดทราบว่าในหน้าคู่มือนี้ปกติ "กระบวนการเรียก" สอดคล้องกับ "กระบวนการหลัก" แต่ดูคำอธิบายของ CLONE_PARENT ด้านล่าง)

การใช้งานหลักของ clone () คือการใช้เธรด: หลายเธรดของการควบคุมในโปรแกรมที่ทำงานพร้อมกันในพื้นที่หน่วยความจำที่ใช้ร่วมกัน

ความแตกต่างมาจากธงที่ถูกส่งไปยังโคลน () อย่างที่คุณเห็นจากหน้า man fork และ threading เป็นเพียงชุดของพารามิเตอร์ที่กำหนดไว้ล่วงหน้าเพื่อโคลน () อย่างไรก็ตามยังสามารถทำสิ่งที่กำหนดเองกับมัน


1
อืม? อะไร? โปรดอ่านหนังสือทุกเล่มในหัวข้ออีกครั้งเนื่องจากพื้นที่หน่วยความจำแยกสำหรับกระบวนการต่าง ๆ เป็นเรื่องใหญ่ นอกจากนี้ยังช่วยให้ "จับ" โค้ดที่ล้มเหลวในขณะที่เคอร์เนลก็จะฆ่ากระบวนการที่แต่ละเธรดไปยุ่งเหยิง / การบุกรุก
0xC0000022L

3
@ 0xC0000022L อาร์กิวเมนต์ของคุณไม่ขัดแย้งกับคำตอบอย่างที่ฉันคิด
Ruslan

1
@ Ruslan: ฉันขอแตกต่าง: "ความคิด [... ] เป็นเรื่องเดียวกัน"? แนวคิดเบื้องหลังเธรดนั้นเป็นสิ่งที่เกิดขึ้นพร้อมกัน แต่สำหรับกระบวนการนี่เป็นเรื่องราวที่แตกต่างอย่างสิ้นเชิง
0xC0000022L

4
@ 0xC0000022L คุณพลาดส่วนสำคัญของคำตอบของ V13: "You fork the path path" - คำถามเกี่ยวกับว่าเธรดจะเกิดอย่างไรไม่ใช่ความแตกต่างระหว่างเธรดและกระบวนการ
Izkata

@Izkata: ไม่เลย ฉันเพิ่งถือว่านี่ไม่ใช่การเรียกร้องที่ถูกต้อง
0xC0000022L

8

ระบบปฏิบัติการหลายตัวที่ไม่ใช่ Unix ส่วนใหญ่จะใช้การเรียก "spawn ()" หรือบางอย่างที่คล้ายกันเพื่อสร้างกระบวนการ OS ใหม่หรือการควบคุมการไหล วางไข่ () มีแนวโน้มที่จะเป็นสายที่ซับซ้อนมากมีตัวเลือกมากมายและค่าใช้จ่ายมากมาย หนึ่งในนวัตกรรมของ Unix คือการให้วิธีการสร้างค่าใช้จ่ายที่ต่ำกว่ามาก - fork () ยูนิกซ์ดูแลตัวเลือกที่จำเป็นมากมายในการวางไข่ () โดยอนุญาตให้มีการประมวลผลจำนวนมากก่อนที่จะวางไข่อีกครึ่งหนึ่ง () พร้อมกับ exec ()

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

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


1
"การจัดการการกำหนดเวลาแบบมัลติเธรดนั้นยุ่งยากและมักจะทำผิดพลาด" การใช้งานเธรดพื้นที่ผู้ใช้ไม่ใช่ปัญหา ปัญหาของเธรดพื้นที่ผู้ใช้คือถ้าเธรดทำการบล็อก syscall เธรดทั้งหมดจะถูกบล็อก วิธีเดียวที่จะหลีกเลี่ยงปัญหานี้คือการใช้เธรดระดับระบบ
Bakuriu

1
ที่น่าสนใจของ Windows ไม่ได้รวมนวัตกรรมนี้ใช้ระบบปฏิบัติการยูนิกซ์: ก็มีแต่ไม่มีอะไรที่คล้ายกับCreateProcess() fork()
Ruslan

2
@Bakuriu - ค้นหาบทความหลาย ๆ บทความเกี่ยวกับการสร้างตารางเวลาแบบมัลติโพรเซสเซอร์การรักษาความเป็นธรรมการหลีกเลี่ยงความอดอยากการจัดการลำดับความสำคัญ ฯลฯ การใช้งานเธรดพื้นที่ผู้ใช้ไม่ใช่อย่างที่คุณพูดถึงปัญหา การจัดตารางตัวอย่างที่ไม่สำคัญนั้นเป็นเรื่องยาก
mpez0

@Ruslan: หนึ่งสามารถแยกบน Windows มันไม่ได้เป็นส่วนหนึ่งของ Win32 API อ่าน "The Windows NT / 2000 Native API" โดย Nebbett fork()เขามีการดำเนินการที่เลียนแบบ
0xC0000022L

3

เธรดและการฟอร์กเป็นแนวคิดที่แตกต่างกันสองข้อซึ่งทั้งคู่มีอยู่ในระบบ Unix / Linux (และทั้งคู่สามารถใช้ใน C / C ++)

แนวคิดของ fork () คือ (โดยพื้นฐานแล้ว) การสร้างกระบวนการแยกต่างหากซึ่งมีรหัสการดำเนินการเช่นเดียวกับกระบวนการหลักและเริ่มต้นการดำเนินการที่แยกบรรทัด วัตถุประสงค์ของการใช้ส้อมกับฟังก์ชั่น exec คือฟังก์ชั่น exec ปิดกระบวนการที่เรียกพวกเขาเมื่อพวกเขาจบ ดังนั้นคุณมักจะแยกรับ PID ของแต่ละกระบวนการ (ของเด็กคือ 0 เสมอ) และทำให้ผู้ปกครองรอจนกว่าเด็กจะดำเนินการฟังก์ชัน exec เสร็จสิ้น

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

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

แก้ไข # 1

โปรดดูตัวอย่างเหล่านี้ว่าสามารถเรียกใช้และใช้ส้อมและกระทู้ได้อย่างไร โปรดทราบพฤติกรรมของฟังก์ชั่น exec และผลกระทบต่อโปรแกรมหลัก

http://www.jdembrun.com:4352/computerScience/forkVSthread.zip


2
Fork (มีหรือไม่มี exec) สามารถใช้สำหรับ parallelism ได้เช่นกัน ฉันไม่แน่ใจว่าสิ่งที่คุณหมายถึงโดย "ฟังก์ชั่น exec ปิดกระบวนการที่เรียกพวกเขาเมื่อพวกเขาจบ", exec จะเสร็จสิ้นการทำงานนานเมื่อกระบวนการสิ้นสุด ยังpthreadเป็น API ไม่ใช่การใช้เธรด
Mat

ในทางแยกฉันพูดถึงอาจารย์ของฉัน ตามที่เขาบอกเราว่าใช่การฟอร์กสามารถใช้ในการทำงานแบบขนาน แต่ถ้ามันใช้ฟังก์ชั่น exec นั่นจะเป็นครั้งสุดท้าย สำหรับ pthread มันมีความหมายเป็นตัวอย่าง
jaredad7

Exec จะเป็นสายสุดท้ายในรหัสของผู้โทรไม่ใช่คำสั่งสุดท้ายของกระบวนการแยก กระบวนการที่ถูกแยกจะมีชีวิตอยู่กับการเรียกใช้รหัส exec'd
Mat

ความคิดเห็นของคุณทำให้ฉันต้องทดสอบสิ่งเหล่านี้ ฉันได้เขียนบางโปรแกรม c ++ ซึ่งแสดงให้เห็นถึงพฤติกรรมของฟังก์ชั่น exec และผลกระทบต่อโปรแกรมเมื่อใช้ใน forks กับกระทู้ โปรดดูการแก้ไขด้านบน
jaredad7

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

1

ทั้ง JVM และ Apache MPM ขึ้นอยู่กับเคอร์เนลสำหรับเธรดพื้นฐาน กล่าวคือพวกเขาใช้ระบบปฏิบัติการเพื่อจัดตารางเวลา แน่นอนว่าทั้งคู่ต้องการ API ของตัวเองเพื่อติดตามเนื้อหา

Stackoverflow มีคำถามหลายข้อที่เกี่ยวข้องกับสิ่งนี้:

  1. เธรด JVM ดั้งเดิมตรวจสอบคำตอบนี้สำหรับรายละเอียดเพิ่มเติม

  2. Apache มีสองประเภทของ MPMs: Prefork กับหนึ่งในขั้นตอนต่อด้ายและคนงานซึ่งมีหน้าที่จัดการหลายหัวข้อ: Apache MPMs ตรวจสอบการอ้างอิงถึงcodebucket


1

หากการฟอร์กใช้ fork + exec เพื่อวางไข่กระบวนการเวอร์ชันขั้นสูงสำหรับเธรดคืออะไร JVM หรือ Worker MPM มีเธรดอย่างไร

นั่นเป็นแพลตฟอร์มเฉพาะ แต่บน linux และฉันคิดว่าระบบที่สอดคล้องกับ POSIX อื่น ๆ อีกมากมายที่พวกเขาใช้การนำไปใช้ในท้องถิ่นของpthreadsซึ่งเป็น userland threading API เช่น:

#include <pthread.h>

pthread_t tid;
pthread_create(&tid, NULL, somefunc, NULL);

เริ่มการเรียกเธรดใหม่somefuncเป็นจุดแรกของการดำเนินการ

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

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