เมื่อใดที่จะเรียก fork () และ exec () ด้วยตัวเอง?


9

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


2
forkbomb ดั้งเดิม: ในขณะที่ (1) ส้อม (); เพื่อทรัพยากรระบบหมู
Joshua

คำตอบ:


22

แน่นอน! รูปแบบทั่วไปในโปรแกรม "wrapper" คือการทำสิ่งต่าง ๆ แล้วแทนที่ตัวเองด้วยโปรแกรมอื่นด้วยการexecโทรเท่านั้น(ไม่มีทางแยก)

#!/bin/sh
export BLAH_API_KEY=blub
...
exec /the/thus/wrapped/program "$@"

ตัวอย่างในชีวิตจริงของเรื่องนี้คือGIT_SSH(แม้ว่าgit(1)จะยังมีGIT_SSH_COMMANDถ้าคุณไม่ต้องการที่จะทำวิธีการโปรแกรม wrapper ข้างต้น)

Fork-only จะใช้เมื่อวางไข่เป็นกลุ่มของกระบวนการผู้ปฏิบัติงานโดยทั่วไป (เช่น Apache httpdในโหมด fork (แม้ว่า fork-only จะเหมาะกับกระบวนการที่ต้องเผาซีพียูให้มากขึ้นและไม่ใช่ที่ใช้นิ้วโป้งยกนิ้วรอให้ I / O เครือข่ายเกิดขึ้น) ) หรือการแยกสิทธิพิเศษที่ใช้โดยsshdและโปรแกรมอื่น ๆ ใน OpenBSD (ไม่มีการประมวลผล)

$ doas pkg_add pstree
...
$ pstree | grep sshd
 |-+= 70995 root /usr/sbin/sshd
 | \-+= 28571 root sshd: jhqdoe [priv] (sshd)
 |   \-+- 14625 jhqdoe sshd: jhqdoe@ttyp6 (sshd)

rootsshd ได้เชื่อมต่อกับลูกค้าคดเคี้ยวออกสำเนาของตัวเอง (28571) แล้วสำเนาอื่น (14625) สำหรับการแยกสิทธิพิเศษ


14

มีมากมาย

โปรแกรมที่เรียกfork()โดยไม่ต้องexec()ทำตามรูปแบบของการวางไข่กระบวนการผู้ปฏิบัติงานเด็กเพื่อดำเนินการงานต่าง ๆ ในกระบวนการแยกจากกันไปยังกระบวนการหลัก คุณจะได้พบนี้ในโปรแกรมที่หลากหลายdhclient, และphp-fpmurxvtd

โปรแกรมที่เรียกexec()ได้โดยไม่ต้องfork()เป็นโหลดห่วงโซ่ซ้อนทับกระบวนการที่มีภาพโปรแกรมที่แตกต่างกัน มีวัฒนธรรมย่อยทั้งหมดของยูทิลิตี้การโหลดเชนที่ทำสิ่งเฉพาะในการประมวลผลสถานะจากนั้นเรียกใช้งานโปรแกรมอื่นเพื่อทำงานกับสถานะกระบวนการที่แก้ไข ยูทิลิตีดังกล่าวเป็นเรื่องธรรมดาในชุดบริการdaemontoolsและชุดเครื่องมือการจัดการระบบ แต่ไม่ จำกัด เฉพาะ ตัวอย่างบางส่วน:

toolsets daemontools ครอบครัวมีจำนวนมากของเครื่องมือดังกล่าวจากmachineenvผ่านไปfind-matching-jvmruntool


2

นอกเหนือไปจากคำตอบอื่น ๆ , debuggers ใช้ptraceโดยทั่วไปแล้วจะใช้ประโยชน์จากช่องว่างระหว่างและfork execผู้ดีบั๊กควรทำเครื่องหมายด้วยตัวเองPTRACE_TRACEMEเพื่อระบุว่ามันกำลังถูกติดตามโดยกระบวนการหลัก - ตัวดีบั๊ก นี่คือการให้สิทธิ์ที่จำเป็นในการดีบักเกอร์

ดังนั้นตัวดีบักจะแยกตัวเองก่อน เด็กจะเรียกptraceด้วยแล้วโทรPTRACE_TRACEME execไม่ว่าโปรแกรมใดที่ exec ของเด็กจะสามารถติดตามได้โดยผู้ปกครอง


มีหลายตัวอย่างของการทำสิ่งต่าง ๆ ระหว่างทางแยกและผู้บริหารการเปลี่ยนเส้นทาง I / O ที่พบบ่อยที่สุด (เช่นการตั้งค่าไพพ์) แต่คำถามนั้นเกี่ยวกับการทำ fork โดยที่ไม่มีผู้บริหารใด ๆ เลย
Barmar

0

ผู้บริหารโดยไม่ต้องใช้ส้อม

มีเหตุผลอย่างน้อยสองประการที่คุณต้องการทำสิ่งนี้:

  1. โหลดโซ่ อิมเมจกระบวนการปัจจุบันถูกแทนที่ด้วยบางสิ่งที่แตกต่าง
  2. การรีสตาร์ทโปรแกรมที่กำลังทำงานอยู่ (ตัวอย่างเช่นอาจเกิดขึ้นเมื่อคุณ SIGHUP หรือกระบวนการเซิร์ฟเวอร์โหลดใหม่ทุกอย่างและเริ่มต้นใหม่อย่างสมบูรณ์) ในทางใดทางหนึ่งเราอาจโต้เถียงว่านี่เป็นการโหลดเชนโดยบังเอิญกับโปรแกรมเดียวกันเท่านั้น

ส้อมโดยไม่ต้อง exec

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

การใช้งานทั่วไปอีกอย่างหนึ่งคือการฟอร์กกิ้งเด็ก ๆ ซึ่งสร้างชื่อเสียงจากเว็บเซิร์ฟเวอร์ apache เมื่อ 25 ปีก่อน (ปัจจุบันนี้ไม่ถือว่าเป็นศิลปะอีกต่อไปแล้วเนื่องจากมีแนวโน้มที่จะเกิดปัญหาฝูงวัวที่รุนแรง สาปเซิร์ฟเวอร์ที่ง่ายที่สุดและทนทานที่สุด)

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


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