Fork System Call ใน C

Fork System Call C



การเรียกระบบ fork() ใช้สำหรับสร้างโปรเซสลูกในโปรแกรม C fork() ใช้เมื่อต้องการการประมวลผลแบบขนานในแอปพลิเคชันของคุณ ฟังก์ชันระบบ fork() ถูกกำหนดในส่วนหัว sys/types.h และ unistd.h . ในโปรแกรมที่คุณใช้ fork คุณต้องใช้ wait() system call ด้วย wait() system call ใช้เพื่อรอในกระบวนการหลักเพื่อให้กระบวนการลูกเสร็จสิ้น เพื่อสิ้นสุดกระบวนการลูก การเรียกระบบ exit() ถูกใช้ในกระบวนการลูก ฟังก์ชั่น wait() ถูกกำหนดในส่วนหัว sys/wait.h และฟังก์ชัน exit() ถูกกำหนดในส่วนหัว stdlib.h .

รูปที่ 1: เวิร์กโฟลว์พื้นฐาน fork()

รูปที่ 1: เวิร์กโฟลว์พื้นฐาน fork()







ในบทความนี้ ผมจะแสดงให้คุณเห็นถึงวิธีการใช้ fork() system call เพื่อสร้างโปรเซสลูกใน C มาเริ่มกันเลยดีกว่า



fork() ไวยากรณ์และค่าส่งคืน:

ไวยากรณ์ของฟังก์ชันระบบ fork() มีดังนี้:



pid_t ส้อม(โมฆะ);

ฟังก์ชันระบบ fork() ไม่ยอมรับอาร์กิวเมนต์ใดๆ ส่งกลับจำนวนเต็มของ type pid_t .





เมื่อสำเร็จ fork() จะส่งกลับ PID ของโปรเซสลูกซึ่งมากกว่า 0 ภายในโปรเซสลูก ค่าที่ส่งคืนคือ 0 หาก fork() ล้มเหลว จะส่งกลับ -1

ส้อมง่าย ๆ () ตัวอย่าง:

ตัวอย่าง fork() อย่างง่ายได้รับด้านล่าง:



#รวม
#รวม
#รวม
#รวม
#รวม

intหลัก(โมฆะ) {
pid_t pid=ส้อม();

ถ้า(pid== 0) {
printf ('ลูก => PPID: %d PID: %dNS',getppid(),getpid());
ทางออก (EXIT_SUCCESS);
}
อื่น ถ้า(pid> 0) {
printf ('ผู้ปกครอง => PID: %dNS',getpid());
printf ('รอให้กระบวนการลูกเสร็จสิ้น.NS');
รอ(โมฆะ);
printf ('กระบวนการลูกเสร็จแล้ว.NS');
}
อื่น {
printf ('ไม่สามารถสร้างกระบวนการย่อยได้NS');
}

กลับEXIT_SUCCESS;
}

ที่นี่ ฉันใช้ fork() เพื่อสร้างกระบวนการลูกจากกระบวนการหลัก/หลัก จากนั้น ฉันพิมพ์ PID (Process ID) และ PPID (Parent Process ID) จากโปรเซสลูกและพาเรนต์ ในกระบวนการหลัก wait(NULL) ใช้เพื่อรอให้กระบวนการย่อยเสร็จสิ้น ในกระบวนการลูก exit() ใช้เพื่อสิ้นสุดกระบวนการลูก อย่างที่คุณเห็น PID ของกระบวนการหลักคือ PPID ของกระบวนการลูก ดังนั้นกระบวนการลูก 24738 อยู่ในกระบวนการหลัก 24731 .

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

#รวม
#รวม
#รวม
#รวม
#รวม

โมฆะงานเด็ก() {
printf ('สวัสดีชาวโลกNS');
}

โมฆะparentTask() {
printf ('งานหลัก.NS');
}

intหลัก(โมฆะ) {
pid_t pid=ส้อม();

ถ้า(pid== 0) {
งานเด็ก();
ทางออก (EXIT_SUCCESS);
}
อื่น ถ้า(pid> 0) {
รอ(โมฆะ);
parentTask();
}
อื่น {
printf ('ไม่สามารถสร้างกระบวนการย่อยได้');
}

กลับEXIT_SUCCESS;
}

ผลลัพธ์ของโปรแกรมข้างต้น:

เรียกใช้กระบวนการลูกหลายรายการโดยใช้ fork() และวนซ้ำ:

คุณยังสามารถใช้ลูปเพื่อสร้างกระบวนการย่อยได้มากเท่าที่คุณต้องการ ในตัวอย่างด้านล่าง ฉันได้สร้างโปรเซสลูก 5 โปรเซสโดยใช้ for loop ฉันยังพิมพ์ PID และ PPID จากกระบวนการลูก

#รวม
#รวม
#รวม
#รวม
#รวม

intหลัก(โมฆะ) {
สำหรับ(intผม= 1;ผม<= 5;ผม++) {
pid_t pid=ส้อม();

ถ้า(pid== 0) {
printf ('กระบวนการลูก => PPID=%d, PID=%dNS',getppid(),getpid());
ทางออก (0);
}
อื่น {
printf ('กระบวนการหลัก => PID=%dNS',getpid());
printf ('กำลังรอกระบวนการลูกให้เสร็จ...NS');
รอ(โมฆะ);
printf ('กระบวนการลูกเสร็จแล้ว.NS');
}
}

กลับEXIT_SUCCESS;
}

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

ตัวอย่างชีวิตจริง:

การคำนวณทางคณิตศาสตร์ที่ซับซ้อนต่างๆ เช่น md5, sha256 ฯลฯ การสร้างแฮชต้องใช้พลังในการประมวลผลจำนวนมาก แทนที่จะคำนวณสิ่งต่าง ๆ เช่นนั้นในกระบวนการเดียวกับโปรแกรมหลัก คุณสามารถคำนวณแฮชในกระบวนการย่อยและส่งคืนแฮชไปยังกระบวนการหลัก

ในตัวอย่างต่อไปนี้ ฉันได้สร้างรหัส PIN 4 หลักในกระบวนการย่อยและส่งไปที่กระบวนการหลัก ซึ่งเป็นโปรแกรมหลัก จากนั้นฉันก็พิมพ์รหัส PIN จากที่นั่น

#รวม
#รวม
#รวม
#รวม
#รวม

intgetPIN() {
// ใช้ PPID และ PID เป็น seed
srand (getpid() +getppid());
intความลับ= 1000 + แถว () % 9000;
กลับความลับ;
}

intหลัก(โมฆะ) {
intfd[2];
ท่อ(fd);
pid_t pid=ส้อม();

ถ้า(pid> 0) {
ปิด(0);
ปิด(fd[1]);
หลังจาก(fd[0]);

intsecretNumber;
size_treadBytes=อ่าน(fd[0], &secretNumber, ขนาดของ(secretNumber));

printf ('กำลังรอ PIN...NS');
รอ(โมฆะ);
printf ('ไบต์ที่อ่าน: %ldNS',readBytes);
printf ('PIN: %dNS',secretNumber);
}
อื่น ถ้า(pid== 0) {
ปิด(1);
ปิด(fd[0]);
หลังจาก(fd[1]);

intความลับ=getPIN();
เขียน(fd[1], &ความลับ, ขนาดของ(ความลับ));
ทางออก (EXIT_SUCCESS);
}

กลับEXIT_SUCCESS;
}

อย่างที่คุณเห็น ทุกครั้งที่ฉันเปิดโปรแกรม ฉันจะได้รับรหัส PIN 4 หลักที่แตกต่างกัน

นั่นคือวิธีที่คุณใช้การเรียกระบบ fork() ใน Linux ขอบคุณที่อ่านบทความนี้