ระบบท่อเรียกในC

Pipe System Call C



ท่อ() เป็นฟังก์ชันระบบลินุกซ์ NS ท่อ() ฟังก์ชันระบบใช้เพื่อเปิด file descriptors ซึ่งใช้ในการสื่อสารระหว่างกระบวนการต่างๆ ของ Linux ในระยะสั้น ท่อ() ฟังก์ชั่นใช้สำหรับการสื่อสารระหว่างกระบวนการใน Linux ในบทความนี้ ผมจะแสดงวิธีการใช้ฟังก์ชันระบบ pipe() ใน Linux มาเริ่มกันเลยดีกว่า

ไวยากรณ์ของ ท่อ() หน้าที่คือ:







intท่อ(intpipefd[2]);

ที่นี่ ฟังก์ชัน pipe() สร้างช่องข้อมูลแบบทิศทางเดียวสำหรับการสื่อสารระหว่างกระบวนการ คุณผ่านใน an int (จำนวนเต็ม) ชนิด array pipefd ประกอบด้วย 2 องค์ประกอบอาร์เรย์ไปยังฟังก์ชัน pipe() จากนั้นฟังก์ชันไพพ์ () จะสร้างตัวอธิบายไฟล์สองตัวใน pipefd อาร์เรย์



องค์ประกอบแรกของ pipefd อาร์เรย์ ปิเปต[0] ใช้สำหรับอ่านข้อมูลจากท่อ



องค์ประกอบที่สองของ pipefd อาร์เรย์ ปิเปต[1] ใช้สำหรับเขียนข้อมูลลงท่อ





เมื่อสำเร็จ ฟังก์ชัน pipe() จะคืนค่า 0 หากเกิดข้อผิดพลาดระหว่างการเริ่มต้นไพพ์ ฟังก์ชันไพพ์ () จะส่งกลับ -1

ฟังก์ชั่น pipe() ถูกกำหนดในส่วนหัว unistd.h . ในการใช้ฟังก์ชัน pipe() ในโปรแกรม C คุณต้องใส่ header unistd.h ดังนี้



#รวม

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับฟังก์ชันระบบ pipe() ให้ตรวจสอบ man page ของ pipe() ด้วยคำสั่งต่อไปนี้:

$ ชาย2ท่อ
หน้าคนของท่อ().

ตัวอย่างที่ 1:

สำหรับตัวอย่างแรก ให้สร้างไฟล์ต้นฉบับ C ใหม่ 1_pipe.c และพิมพ์รหัสบรรทัดต่อไปนี้

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

intหลัก(โมฆะ) {
intpipefds[2];

ถ้า(ท่อ(pipefds) == -1) {
ความผิดพลาด ('ท่อ');
ทางออก (EXIT_FAILURE);
}

printf ('อ่านค่าตัวอธิบายไฟล์: %dNS',pipefds[0]);
printf ('เขียนค่าตัวอธิบายไฟล์: %dNS',pipefds[1]);

กลับEXIT_SUCCESS;
}

ที่นี่ฉันรวมไฟล์ส่วนหัวของ pipe() unistd.h ก่อนด้วยบรรทัดต่อไปนี้

#รวม

จากนั้นใน หลัก() ฟังก์ชัน ฉันกำหนด pipefds อาร์เรย์จำนวนเต็มสององค์ประกอบที่มีบรรทัดต่อไปนี้

intpipefds[2];

จากนั้น ฉันเรียกใช้ฟังก์ชัน pipe() เพื่อเริ่มต้น file descriptors array pipefds ดังนี้

ท่อ(pipefds)

ฉันยังตรวจสอบข้อผิดพลาดโดยใช้ค่าส่งคืนของฟังก์ชัน pipe() ฉันใช้ ทางออก() ฟังก์ชั่นเพื่อปิดโปรแกรมในกรณีที่ฟังก์ชั่นไปป์ล้มเหลว

ถ้า(ท่อ(pipefds) == -1) {
ความผิดพลาด ('ท่อ');
ทางออก (EXIT_FAILURE);
}

จากนั้นฉันพิมพ์ค่าของตัวอธิบายไฟล์ไปป์อ่านและเขียน ปิเปต[0] และ ปิเปต[1] ตามลำดับ

printf ('อ่านค่าตัวอธิบายไฟล์: %dNS',pipefds[0]);
printf ('เขียนค่าตัวอธิบายไฟล์: %dNS',pipefds[1]);

หากคุณเรียกใช้โปรแกรม คุณจะเห็นผลลัพธ์ต่อไปนี้ อย่างที่คุณเห็น ค่าของ read pipe file descriptor ปิเปต[0] เป็น 3 และเขียนไฟล์ไพพ์ descriptor ปิเปต[1] เป็น 4 .

ตัวอย่างที่ 2:

สร้างไฟล์ต้นฉบับ C อื่น 2_pipe.c และพิมพ์รหัสบรรทัดต่อไปนี้

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

intหลัก(โมฆะ) {
intpipefds[2];
charกันชน[5];

ถ้า(ท่อ(pipefds) == -1) {
ความผิดพลาด ('ท่อ');
ทางออก (EXIT_FAILURE);
}

char *เข็มหมุด= '4128 0';

printf ('กำลังเขียน PIN ไปป์...NS');
เขียน(pipefds[1],เข็มหมุด, 5);
printf ('เสร็จแล้ว.NSNS');

printf ('กำลังอ่าน PIN จากไปป์...NS');
อ่าน(pipefds[0],กันชน, 5);
printf ('เสร็จแล้ว.NSNS');

printf ('PIN จากไปป์: %sNS',กันชน);

กลับEXIT_SUCCESS;
}

โดยทั่วไป โปรแกรมนี้จะแสดงวิธีเขียนไปยังไพพ์และอ่านข้อมูลที่คุณเขียนจากไพพ์

ที่นี่ ฉันเก็บรหัส PIN 4 ตัวไว้ใน a char อาร์เรย์ ความยาวของอาร์เรย์คือ 5 (รวมอักขระ NULL )

char *เข็มหมุด= '4128 0';

อักขระ ASCII แต่ละตัวมีขนาด 1 ไบต์ในภาษา C ดังนั้น ในการส่ง PIN 4 หลักผ่านไพพ์ คุณต้องเขียนข้อมูล 5 ไบต์ (4 + 1 NULL character) ของข้อมูลลงในไพพ์

ในการเขียนข้อมูล 5 ไบต์ ( เข็มหมุด ) ลงในท่อฉันใช้ เขียน() ฟังก์ชันโดยใช้ตัวอธิบายไฟล์ไพพ์เขียน ปิเปต[1] ดังนี้

เขียน(pipefds[1],เข็มหมุด, 5);

ตอนนี้ฉันมีข้อมูลบางส่วนในไพพ์แล้ว ฉันสามารถอ่านได้จากไพพ์โดยใช้ อ่าน() ฟังก์ชั่นบนตัวอธิบายไฟล์อ่านไปป์ ปิเปต[0] . ตามที่ฉันเขียนข้อมูล 5 ไบต์ ( เข็มหมุด ) ลงในไพพ์ ผมจะอ่านข้อมูล 5 ไบต์จากไพพ์ด้วย ข้อมูลที่อ่านจะถูกเก็บไว้ใน กันชน อาร์เรย์อักขระ ในขณะที่ฉันจะอ่านข้อมูล 5 ไบต์จากไพพ์ กันชน อาร์เรย์อักขระต้องมีความยาวอย่างน้อย 5 ไบต์

ฉันได้กำหนด กันชน อาร์เรย์อักขระที่จุดเริ่มต้นของ หลัก() การทำงาน.

charกันชน[5];

ตอนนี้ ฉันสามารถอ่าน PIN จากไปป์และเก็บไว้ใน กันชน อาร์เรย์ด้วยบรรทัดต่อไปนี้

อ่าน(pipefds[0],กันชน, 5);

ตอนนี้ฉันอ่าน PIN จากไปป์แล้ว ฉันสามารถพิมพ์ได้โดยใช้ปุ่ม พิมพ์f() ใช้งานได้ตามปกติ

printf ('PIN จากไปป์: %sNS',กันชน);

เมื่อฉันเรียกใช้โปรแกรม ผลลัพธ์ที่ถูกต้องจะแสดงดังที่คุณเห็น

ตัวอย่างที่ 3:

สร้างไฟล์ต้นฉบับ C ใหม่ 3_pipe.c ตามที่พิมพ์ในบรรทัดของรหัสต่อไปนี้

#รวม
#รวม
#รวม
#รวม
#รวม
intหลัก(โมฆะ) {
intpipefds[2];
char *เข็มหมุด;
charกันชน[5];

ถ้า(ท่อ(pipefds) == -1) {
ความผิดพลาด ('ท่อ');
ทางออก (EXIT_FAILURE);
}

pid_t pid=ส้อม();

ถ้า(pid== 0) { // อยู่ในกระบวนการลูก
เข็มหมุด= '4821 0'; // PIN เพื่อส่ง
ปิด(pipefds[0]); // ปิดการอ่าน fd
เขียน(pipefds[1],เข็มหมุด, 5); // เขียน PIN ไปยังไพพ์

printf ('กำลังสร้าง PIN ในลูกและส่งให้ผู้ปกครอง...NS');
นอน(2); //ตั้งใจล่าช้า
ทางออก (EXIT_SUCCESS);
}

ถ้า(pid> 0) { // อยู่ในกระบวนการหลัก
รอ(โมฆะ); // รอให้กระบวนการลูกเสร็จสิ้น
ปิด(pipefds[1]); // ปิดการเขียน fd
อ่าน(pipefds[0],กันชน, 5); // อ่าน PIN จากไพพ์
ปิด(pipefds[0]); // ปิดการอ่าน fd

printf ('ผู้ปกครองได้รับ PIN '%s'NS',กันชน);
}

กลับEXIT_SUCCESS;
}

ในตัวอย่างนี้ ฉันแสดงให้คุณเห็นถึงวิธีใช้ไพพ์สำหรับการสื่อสารระหว่างกระบวนการ ฉันได้ส่ง PIN จากกระบวนการลูกไปยังกระบวนการหลักโดยใช้ไพพ์ จากนั้นอ่าน PIN จากไพพ์ในกระบวนการหลัก และพิมพ์จากกระบวนการหลัก

ขั้นแรก ฉันได้สร้างกระบวนการย่อยโดยใช้ฟังก์ชัน fork()

pid_t pid=ส้อม();

จากนั้นในกระบวนการลูก ( pid == 0 ) ฉันเขียน PIN ไปยังไพพ์โดยใช้ เขียน() การทำงาน.

เขียน(pipefds[1],เข็มหมุด, 5);

เมื่อ PIN ถูกเขียนไปยังไพพ์จากโปรเซสลูก โปรเซสพาเรนต์ ( pid > 0 ) อ่านจากท่อโดยใช้ อ่าน() การทำงาน.

อ่าน(pipefds[0],กันชน, 5);

จากนั้นกระบวนการหลักจะพิมพ์ PIN โดยใช้ พิมพ์f() ใช้งานได้ตามปกติ

printf ('ผู้ปกครองได้รับ PIN '%s'NS',กันชน);

อย่างที่คุณเห็น การรันโปรแกรมจะให้ผลลัพธ์ที่คาดหวัง

ตัวอย่างที่ 4:

สร้างไฟล์ต้นฉบับ C ใหม่ 4_pipe.c ตามที่พิมพ์ในบรรทัดของรหัสต่อไปนี้

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

#กำหนด PIN_LENGTH 4
#กำหนด PIN_WAIT_INTERVAL 2

โมฆะgetPIN(charเข็มหมุด[PIN_LENGTH+ 1]) {
srand (getpid() +getppid());

เข็มหมุด[0] = 49 + แถว () % 7;

สำหรับ(intผม= 1;ผม<PIN_LENGTH;ผม++) {
เข็มหมุด[ผม] = 48 + แถว () % 7;
}

เข็มหมุด[PIN_LENGTH] = ' 0';
}


intหลัก(โมฆะ) {
ในขณะที่(1) {
intpipefds[2];
charเข็มหมุด[PIN_LENGTH+ 1];
charกันชน[PIN_LENGTH+ 1];

ท่อ(pipefds);

pid_t pid=ส้อม();

ถ้า(pid== 0) {
getPIN(เข็มหมุด); // สร้าง PIN
ปิด(pipefds[0]); // ปิดการอ่าน fd
เขียน(pipefds[1],เข็มหมุด,PIN_LENGTH+ 1); // เขียน PIN ไปยังไพพ์

printf ('กำลังสร้าง PIN ในลูกและส่งให้ผู้ปกครอง...NS');

นอน(PIN_WAIT_INTERVAL); // ชะลอการสร้าง PIN โดยเจตนา

ทางออก (EXIT_SUCCESS);
}

ถ้า(pid> 0) {
รอ(โมฆะ); //รอลูกเรียนจบ

ปิด(pipefds[1]); // ปิดการเขียน fd
อ่าน(pipefds[0],กันชน,PIN_LENGTH+ 1); // อ่าน PIN จากไพพ์
ปิด(pipefds[0]); // ปิดการอ่าน fd
printf ('ผู้ปกครองได้รับ PIN '%s' จากเด็กNSNS',กันชน);
}
}

กลับEXIT_SUCCESS;
}

ตัวอย่างนี้เหมือนกับ ตัวอย่างที่ 3 . ข้อแตกต่างเพียงอย่างเดียวคือโปรแกรมนี้สร้างกระบวนการย่อยอย่างต่อเนื่อง สร้าง PIN ในกระบวนการย่อย และส่ง PIN ไปยังกระบวนการหลักโดยใช้ไพพ์

กระบวนการหลักจะอ่าน PIN จากไพพ์และพิมพ์ออกมา

โปรแกรมนี้จะสร้าง PIN_LENGTH PIN ใหม่ทุกๆ PIN_WAIT_INTERVAL วินาที

อย่างที่คุณเห็น โปรแกรมทำงานตามที่คาดไว้

คุณสามารถหยุดโปรแกรมได้โดยการกด + .

นี่คือวิธีที่คุณใช้การเรียกระบบ pipe() ในภาษาการเขียนโปรแกรม C ขอบคุณที่อ่านบทความนี้