ฉันได้ยินมาว่า FIFO มีชื่อว่าไพพ์ และพวกเขามีความหมายเดียวกัน ในทางกลับกันฉันคิดว่าซ็อกเก็ตโดเมน Unix ค่อนข้างคล้ายกับไพพ์ (แม้ว่าฉันจะไม่เคยใช้มัน) ดังนั้นฉันสงสัยว่าพวกเขาทั้งหมดอ้างถึงการใช้งานเดียวกันในเคอร์เนล Linux ความคิดใด ๆ
ฉันได้ยินมาว่า FIFO มีชื่อว่าไพพ์ และพวกเขามีความหมายเดียวกัน ในทางกลับกันฉันคิดว่าซ็อกเก็ตโดเมน Unix ค่อนข้างคล้ายกับไพพ์ (แม้ว่าฉันจะไม่เคยใช้มัน) ดังนั้นฉันสงสัยว่าพวกเขาทั้งหมดอ้างถึงการใช้งานเดียวกันในเคอร์เนล Linux ความคิดใด ๆ
คำตอบ:
ซ็อกเก็ตโดเมนของ UNIX และ FIFO อาจแบ่งปันบางส่วนของการนำไปใช้ แต่มีแนวคิดแตกต่างกันมาก ฟังก์ชั่น FIFO ในระดับต่ำมาก หนึ่งกระบวนการเขียนไบต์ลงในไพพ์และอีกอันหนึ่งอ่านจากมัน ซ็อกเก็ตโดเมน UNIX มีพฤติกรรมเช่นเดียวกับซ็อกเก็ต TCP / IP
ซ็อกเก็ตเป็นแบบสองทิศทางและสามารถใช้กระบวนการจำนวนมากพร้อมกัน กระบวนการสามารถยอมรับการเชื่อมต่อจำนวนมากในซ็อกเก็ตเดียวกันและเข้าร่วมหลายไคลเอ็นต์พร้อมกัน เคอร์เนลส่งไฟล์อธิบายใหม่ทุกครั้งconnect(2)
หรือaccept(2)
ถูกเรียกบนซ็อกเก็ต แพ็กเก็ตจะไปยังกระบวนการที่ถูกต้องเสมอ
บน FIFO สิ่งนี้จะเป็นไปไม่ได้ สำหรับการสื่อสารสองทิศทางคุณต้องมี FIFO สองตัวและคุณต้องการ FIFO สองคู่สำหรับลูกค้าของคุณแต่ละคน ไม่มีวิธีเขียนหรืออ่านในลักษณะที่เลือกได้เนื่องจากเป็นวิธีการสื่อสารแบบดั้งเดิม
ท่อที่ไม่ระบุชื่อและ FIFO นั้นคล้ายกันมาก แตกต่างก็คือท่อที่ไม่ระบุชื่อไม่ได้อยู่เป็นไฟล์ในระบบแฟ้มเพื่อให้กระบวนการที่ไม่สามารถopen(2)
มัน พวกเขาจะถูกใช้โดยกระบวนการที่ใช้ร่วมกันโดยวิธีอื่น หากกระบวนการเปิด FIFOs จากนั้นดำเนินการตัวอย่างเช่นชายfork(2)
ด์ของกระบวนการจะสืบทอดสืบทอดตัวอธิบายไฟล์และไปป์ในหมู่พวกเขา
ซ็อกเก็ตโดเมน UNIX ไพพ์ที่ไม่ระบุชื่อและ FIFO นั้นคล้ายคลึงกันในความเป็นจริงที่พวกเขาใช้กลุ่มหน่วยความจำที่ใช้ร่วมกัน รายละเอียดของการดำเนินการอาจแตกต่างจากระบบหนึ่งไปยังอีก แต่ความคิดที่เป็นแบบเดียวกันเสมอ: แนบส่วนเดียวกันของหน่วยความจำในการทำแผนที่หน่วยความจำกระบวนการที่แตกต่างกันสองถึงพวกเขาได้ใช้ข้อมูลร่วมกัน
( แก้ไข:ที่จะเป็นหนึ่งในวิธีที่ชัดเจนที่จะใช้มัน แต่ที่เป็น ไม่ใช่วิธีที่ใช้ใน Linux ซึ่งใช้หน่วยความจำเคอร์เนลสำหรับบัฟเฟอร์ดูคำตอบโดย @ tjb63 ด้านล่าง)
เคอร์เนลจะจัดการการเรียกของระบบและสรุปกลไก
มีการสนทนาที่ดีของที่นี่: http://www.slideshare.net/divyekapoor/linux-kernel-implementation-of-pipes-and-fifos
เท่าที่ฉันสามารถเห็นได้ทั้งจากสไลด์การนำเสนอและ source @ http://lxr.free-electrons.com/source/fs/pipe.c - มีการนำฟีฟ่ามาใช้เป็น wrapper รอบ ๆ ท่อและตัวท่อเอง ดำเนินการผ่าน pipefs ระบบไฟล์เสมือน ..
@lgeorget - ท่อปรากฏการใช้หน่วยความจำเคอร์เนลสำหรับบัฟเฟอร์ระหว่างผู้อ่านและนักเขียน - พวกเขาไม่ได้ใช้หน่วยความจำที่ใช้ร่วมกันเช่นหน่วยความจำและคัดลอกระหว่างผู้ใช้และที่อยู่เคอร์เนลพื้นที่ (เช่นpipe_read
สายpipe_iov_copy_to_user
ที่โทร__copy_to_user_inatomic
(หรือcopy_to_user
) . __copy_to_user_inatomic
call copy_user_generic
ซึ่งอยู่ในการประยุกต์ใช้ ASM หลายตัว
"FIFO" และ " named pipe" เป็นสิ่งเดียวกัน - แม้ว่ามันจะค่อนข้างแตกต่างจากวิธีที่เชลล์จัดการกับ "pipe" (|) ระหว่างสองคำสั่งบนบรรทัดคำสั่ง
ไปป์ที่มีชื่อ (FIFO) เป็น "ไฟล์" เดียวที่ใช้ร่วมกันโดยสองโปรแกรมโดยที่หนึ่งเขียนไปยังมันและอีกอ่านจากมัน ... ซ็อกเก็ตในมืออื่น ๆ คือ "การเชื่อมต่อ" ระหว่างสอง "ไฟล์" - ซึ่งอาจ ใช้เครือข่ายและอยู่ในคอมพิวเตอร์แยกต่างหาก - ที่หนึ่งโปรแกรมอ่าน / เขียนไปยัง "ไฟล์" หนึ่งและอีกโปรแกรมอ่าน / เขียนไปยังอีก ... ฉันไม่คิดว่าพวกเขาจะคล้ายกัน ... ในอีกทางหนึ่งทั้งสอง ซ็อกเก็ตและไพพ์ที่มีชื่อ - รวมถึงไฟล์อุปกรณ์ลิงก์สัญลักษณ์ - ทั้งหมดใช้ inodes และทั้งหมดใช้คุณสมบัติทั่วไปบางอย่าง (เช่นอ่านและเขียน)
ฉันไม่คิดอย่างนั้นจัสติน ถ้าฉันไม่เข้าใจผิดและฉันอาจเป็นเช่นนั้นฉันคิดว่า FIFO ใช้ไฟล์บนดิสก์และซ็อกเก็ต Unix Domain ใช้หน่วยความจำเคอร์เนล
นอกจากนี้ในฐานะผู้โพสต์ข้างต้นผู้ที่กล่าวว่าซ็อกเก็ตโดเมน Unix เป็นแบบสองทิศทางนั่นเป็นเพียงกรณีเมื่อใช้ซ็อกเก็ต SOCK_STREAM SOCK_DGRAM ซ็อกเก็ตโดเมน Unix คืออันที่จริงแล้วเป็นทิศทางเดียวและสามารถส่ง () จากรหัสที่เรียกว่า connect () ไปยังรหัสที่เรียกว่า bind ()
แน่นอนว่ารหัสที่เรียกว่าการเชื่อมต่อ () จะต้องเรียกการผูก () เพื่อสร้างเป็นจุดสิ้นสุดของตัวเอง แต่ไม่มีส่วนเกี่ยวข้องกับคำถามของคุณ
My 2 cents ... ซ็อกเก็ต FIFO และ UNIX มีทั้งสองทิศทาง (คล้ายกัน) แต่ซ็อกเก็ตมีลักษณะเป็นรูปดาวในขณะที่ FIFO เป็นเพียงคิว (ดังนั้นจึงไม่สามารถแทนที่กันได้) การติดตั้งของพวกเขาอาจใช้รหัสภายใน
**
char * myfifo = "/tmp/myfifo";
mkfifo(myfifo, 0666);
fd = open(myfifo, O_RDWR); //so that you can read/write to it
...
write(fd, buff1, sizeof(buff1));
getchar();//wait till some one reds this and writes something else
int sz=read(fd, buff1, sizeof(buff1)); //read that something**