ในปัญหานี้ เราจะสาธิต fork() และ pipe() ที่นี่เราจะสร้างโปรแกรม C สำหรับ Linux ที่จะต่อสตริงสองสตริง โดยใช้ 2 โปรเซส โปรเซสหนึ่งจะรับอินพุตและส่งให้อีกตัว ซึ่งจะต่อสตริงกับสตริงที่กำหนดไว้ล่วงหน้าและคืนสตริงที่ต่อแล้ว
ก่อนอื่น ให้ ทบทวน fork() และ pipe()
fork() — สร้างโปรเซสลูก (child process) โปรเซสลูกนี้มี PID และ PPID ใหม่
pipe() คือ system call ของ Unix, Linux ที่ใช้สำหรับการสื่อสารระหว่างโปรเซส (inter-process communication)
ตัวอย่างเพื่อเข้าใจปัญหา
อินพุต
Learn programming สตริงที่กำหนดไว้: at tutorialspoint
เอาต์พุต
Learn programming at tutorialspoint
คำอธิบาย
P1 รับอินพุตสตริง "learn programming" ส่งให้ P2 ผ่าน pipe P2 ต่อสตริงและส่งกลับให้ P1 ซึ่งพิมพ์ออกมา
ในโปรแกรม เราจะสร้างสองโปรเซส คือ P1 และ P2 โดยใช้ฟังก์ชัน fork() มีค่าคืนสามค่าที่แสดงสถานะของโปรแกรม
ค่าคืน < 0, การสร้างโปรเซสล้มเหลว
ค่าคืน = 0, โปรเซสลูก
ค่าคืน > 0, ซึ่งจะเป็น Process ID ของโปรเซสลูกให้โปรเซสแม่ นั่นคือ โปรเซสแม่จะถูกทำงาน
เราจะสร้าง pipe สองอัน หนึ่งสำหรับสื่อสารจาก P1 ไป P2 และอีกอันจาก P2 ไป P1 เนื่องจาก pipe เป็นทางเดียว
โปรแกรม C สาธิต fork() และ pipe()
ตัวอย่างโค้ด
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <sys/wait.h>
int main() {
int p12[2];
int p21[2];
char fixed_str[] = " at tutorialspoint";
char input_str[100];
pid_t P;
if (pipe(p12) == -1 || pipe(p21) == -1) {
fprintf(stderr, "สร้าง pipe ไม่สำเร็จ");
return 1;
}
scanf("%s", input_str);
P = fork();
if (P < 0) {
fprintf(stderr, "fork ล้มเหลว");
return 1;
} else if (P > 0) {
// โปรเซสแม่
char concat_str[100];
close(p12[0]);
write(p12[1], input_str, strlen(input_str) + 1);
close(p12[1]);
wait(NULL);
close(p21[1]);
read(p21[0], concat_str, 100);
printf("สตริงที่ต่อแล้ว %s\n", concat_str);
close(p21[0]);
} else {
// โปรเซสลูก
close(p12[1]);
char concat_str[100];
read(p12[0], concat_str, 100);
int k = strlen(concat_str);
int i;
for (i = 0; i < strlen(fixed_str); i++)
concat_str[k++] = fixed_str[i];
concat_str[k] = '\0';
close(p12[0]);
close(p21[0]);
write(p21[1], concat_str, strlen(concat_str) + 1);
close(p21[1]);
exit(0);
}
return 0;
}
ผลลัพธ์
สตริงที่ต่อแล้ว Learn at tutorialspoint