ไปป์เป็นสื่อกลางในการสื่อสารระหว่างกระบวนการ กระบวนการหนึ่งเขียนข้อมูลไปยังไพพ์ และอีกกระบวนการหนึ่งอ่านข้อมูลจากไพพ์ ในบทความนี้ เราจะมาดูกันว่าฟังก์ชัน pipe() ถูกใช้เพื่อนำแนวคิดไปใช้อย่างไรโดยใช้ภาษา C
เกี่ยวกับท่อ
ในไพพ์ ข้อมูลจะถูกรักษาไว้ในลำดับ FIFO ซึ่งหมายถึงการเขียนข้อมูลไปยังปลายด้านหนึ่งของไพพ์ตามลำดับ และอ่านข้อมูลจากปลายอีกด้านหนึ่งของไพพ์ในลำดับเดียวกัน
หากกระบวนการใดอ่านจากไพพ์ แต่ยังไม่มีกระบวนการอื่นที่ยังไม่ได้เขียนไปยังไพพ์ การอ่านจะส่งคืนจุดสิ้นสุดไฟล์ หากกระบวนการต้องการเขียนไปยังไพพ์ แต่ไม่มีกระบวนการอื่นแนบมากับไพพ์เพื่อการอ่าน แสดงว่านี่เป็นเงื่อนไขข้อผิดพลาด และไพพ์จะสร้างสัญญาณ SIGPIPE
ไฟล์ส่วนหัว
#รวมไวยากรณ์
intท่อ(intfiledes[2])
ข้อโต้แย้ง
ฟังก์ชันนี้รับอาร์กิวเมนต์เดียว อาร์เรย์ของจำนวนเต็มสองตัว ( filedes ). ไฟล์[0] ใช้สำหรับอ่านจากท่อและ ไฟล์[1] ใช้สำหรับเขียนลงท่อ กระบวนการที่ต้องการอ่านจากท่อควรปิด ไฟล์[1], และกระบวนการที่ต้องการเขียนลงท่อควรปิดลง ไฟล์[0] . หากไม่ได้ปิดส่วนปลายที่ไม่จำเป็นของไพพ์อย่างชัดเจน end-of-file(EOF) จะไม่ถูกส่งกลับ
ส่งคืนค่า
เมื่อประสบความสำเร็จ ท่อ() คืนค่า 0 สำหรับความล้มเหลว ฟังก์ชันจะส่งกลับ -1
ในภาพเราสามารถเป็นตัวแทนของ ท่อ() ทำหน้าที่ดังต่อไปนี้:
ด้านล่างนี้คือตัวอย่างบางส่วนที่แสดงวิธีการใช้ฟังก์ชันไพพ์ในภาษา C
ตัวอย่าง1
ในตัวอย่างนี้ เราจะมาดูกันว่าฟังก์ชันไปป์ทำงานอย่างไร แม้ว่าการใช้ไพพ์ในกระบวนการเดียวจะไม่มีประโยชน์มากนัก แต่เราจะได้รับแนวคิด
// Example1.c#รวม
#รวม
#รวม
#รวม
intหลัก()
{
intNS;
intfiledes[2];
charกันชน[1025];
char *ข้อความ= 'สวัสดีชาวโลก!';
ท่อ(filedes);
เขียน(filedes[1],ข้อความ, strlen (ข้อความ));
ถ้า ((NS=อ่าน(filedes[0],กันชน, 1024 ) ) > = 0) {
กันชน[NS] = 0; //ยุติสตริง
printf ('อ่าน %d ไบต์จากไพพ์: '%NS'NS',NS,กันชน);
}
อื่น
ความผิดพลาด ('อ่าน');
ทางออก (0);
}
ที่นี่เราได้สร้างไพพ์ขึ้นโดยใช้ ท่อ() ฟังก์ชันแล้วเขียนไปยังไพพ์โดยใช้ งาช้าง [1] จบ. จากนั้นจึงอ่านข้อมูลโดยใช้ปลายอีกด้านของท่อซึ่งก็คือ ไฟล์[0] . สำหรับการอ่านและเขียนไฟล์ เราเคย อ่าน() และ เขียน() ฟังก์ชั่น.
ตัวอย่าง2
ในตัวอย่างนี้ เราจะดูว่าโปรเซสพาเรนต์และโปรเซสลูกสื่อสารกันอย่างไรโดยใช้ไพพ์
// Example2.c#รวม
#รวม
#รวม
#รวม
#รวม
intหลัก()
{
intfiledes[2],nbytes;
pid_t childpid;
charสตริง[] = 'สวัสดีชาวโลก!NS';
charreadbuffer[80];
ท่อ(filedes);
ถ้า((ลูกปิด=ส้อม()) == -1)
{
ความผิดพลาด ('ส้อม');
ทางออก (1);
}
ถ้า(ลูกปิด== 0)
{
ปิด(filedes[0]);//กระบวนการลูกไม่ต้องการปลายท่อนี้
/* ส่ง 'สตริง' ผ่านด้านออกของไพพ์ */
เขียน(filedes[1],สตริง, ( strlen (สตริง)+1));
ทางออก (0);
}
อื่น
{
/* กระบวนการหลักปิดด้านเอาต์พุตของไพพ์ */
ปิด(filedes[1]);//กระบวนการหลักไม่ต้องการจุดสิ้นสุดของไพพ์นี้
/* อ่านเป็นสตริงจากไพพ์ */
nbytes=อ่าน(filedes[0],readbuffer, ขนาดของ(readbuffer));
printf ('อ่านสตริง: %s',readbuffer);
}
กลับ(0);
}
ขั้นแรก มีการสร้างไพพ์หนึ่งท่อโดยใช้ฟังก์ชันไพพ์ จากนั้นโปรเซสลูกจะถูกแยกออก จากนั้นโปรเซสลูกจะปิดจุดสิ้นสุดการอ่านและเขียนไปยังไพพ์ กระบวนการพาเรนต์ปิดจุดสิ้นสุดการเขียนและอ่านจากไพพ์และแสดง การไหลของข้อมูลเป็นเพียงวิธีเดียวเท่านั้นที่มาจากลูกถึงผู้ปกครอง
บทสรุป:
ท่อ() เป็นการเรียกระบบที่ทรงพลังใน Linux ในบทความนี้ เราได้เห็นโฟลว์ข้อมูลทางเดียว กระบวนการหนึ่งเขียน และอีกกระบวนการหนึ่งอ่าน การสร้างสองไพพ์ เราสามารถบรรลุโฟลว์ข้อมูลแบบสองทิศทางได้เช่นกัน