FIFO, pipe & Unix socket socket เป็นสิ่งเดียวกันใน Linux kernel หรือไม่?


30

ฉันได้ยินมาว่า FIFO มีชื่อว่าไพพ์ และพวกเขามีความหมายเดียวกัน ในทางกลับกันฉันคิดว่าซ็อกเก็ตโดเมน Unix ค่อนข้างคล้ายกับไพพ์ (แม้ว่าฉันจะไม่เคยใช้มัน) ดังนั้นฉันสงสัยว่าพวกเขาทั้งหมดอ้างถึงการใช้งานเดียวกันในเคอร์เนล Linux ความคิดใด ๆ


จากคำตอบด้านล่างฉันรู้ว่าคำถามของฉันนั้นคลุมเครือและยากที่จะตอบ เป็นไปได้ว่าจะไม่มีใครรู้รายละเอียดของการใช้งานสิ่งต่างๆในเคอร์เนล (แม้แต่สำหรับผู้พัฒนาเคอร์เนล) หากใครบางคนสามารถยืนยันได้ว่าซ็อกเก็ตโดเมน Unix, ไปป์และ FIFO พวกเขาทั้งหมดบัฟเฟอร์ข้อมูลที่ถูกส่งในหน่วยความจำที่ใช้ร่วมกันภายใต้ Linux, คำถามของฉันจะแก้ไข อืม ... แก้ไขได้แล้วบางส่วน
Justin

FIFO = ชื่อ pipes! = pipes FIFO สามารถเป็นแบบสองทิศทางเหมือนคู่ซ็อกเก็ต ท่อปกติอยู่ในทิศทางเดียว ทั้งหมดมีส่วนต่อประสานและความหมายของไฟล์ ทำไมการติดตั้งจึงมีความสำคัญกับคุณ
PSkocik

ฉันรู้ว่าไพพ์เป็นบัฟเฟอร์วงกลมและด้วยระบบ STREAMS สิ่งเหล่านี้สามารถใช้ร่วมกันได้ แต่ Linux ไม่ได้ใช้ STREAMS ตามค่าเริ่มต้น ฉันเชื่อว่า Linux จะเข้ารหัสช่อง IPC เหล่านี้ได้ แต่ฉันไม่รู้สึกอยากตรวจสอบ : D ทำไมคุณไม่ รหัสนี้เป็นแบบสาธารณะ
PSkocik

หากพวกเขาทั้งหมดมีการใช้งานร่วมกันประสิทธิภาพของพวกเขาควรอยู่ใกล้กัน และสำหรับฉันแล้วรหัสเคอร์เนลนั้นยากเกินกว่าจะเข้าใจได้
Justin

คำตอบ:


35

ซ็อกเก็ตโดเมนของ UNIX และ FIFO อาจแบ่งปันบางส่วนของการนำไปใช้ แต่มีแนวคิดแตกต่างกันมาก ฟังก์ชั่น FIFO ในระดับต่ำมาก หนึ่งกระบวนการเขียนไบต์ลงในไพพ์และอีกอันหนึ่งอ่านจากมัน ซ็อกเก็ตโดเมน UNIX มีพฤติกรรมเช่นเดียวกับซ็อกเก็ต TCP / IP

ซ็อกเก็ตเป็นแบบสองทิศทางและสามารถใช้กระบวนการจำนวนมากพร้อมกัน กระบวนการสามารถยอมรับการเชื่อมต่อจำนวนมากในซ็อกเก็ตเดียวกันและเข้าร่วมหลายไคลเอ็นต์พร้อมกัน เคอร์เนลส่งไฟล์อธิบายใหม่ทุกครั้งconnect(2)หรือaccept(2)ถูกเรียกบนซ็อกเก็ต แพ็กเก็ตจะไปยังกระบวนการที่ถูกต้องเสมอ
บน FIFO สิ่งนี้จะเป็นไปไม่ได้ สำหรับการสื่อสารสองทิศทางคุณต้องมี FIFO สองตัวและคุณต้องการ FIFO สองคู่สำหรับลูกค้าของคุณแต่ละคน ไม่มีวิธีเขียนหรืออ่านในลักษณะที่เลือกได้เนื่องจากเป็นวิธีการสื่อสารแบบดั้งเดิม

ท่อที่ไม่ระบุชื่อและ FIFO นั้นคล้ายกันมาก แตกต่างก็คือท่อที่ไม่ระบุชื่อไม่ได้อยู่เป็นไฟล์ในระบบแฟ้มเพื่อให้กระบวนการที่ไม่สามารถopen(2)มัน พวกเขาจะถูกใช้โดยกระบวนการที่ใช้ร่วมกันโดยวิธีอื่น หากกระบวนการเปิด FIFOs จากนั้นดำเนินการตัวอย่างเช่นชายfork(2)ด์ของกระบวนการจะสืบทอดสืบทอดตัวอธิบายไฟล์และไปป์ในหมู่พวกเขา

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


"ซ็อกเก็ตโดเมน UNIX และ FIFO อาจแบ่งปันบางส่วนของการใช้งาน" ... ประเด็นก็คือ "บางส่วนของ" ... ฉันเพิ่งรู้ว่าคำถามของฉันนั้นคลุมเครือและยากที่จะตอบ เป็นไปได้ว่าจะไม่มีใครรู้รายละเอียดมากมายว่าชิ้นส่วนใดที่พวกเขาแชร์ในเคอร์เนล (แม้แต่ผู้พัฒนาเคอร์เนล) อย่างไรก็ตาม ... ใครสามารถยืนยันได้ว่าซ็อกเก็ตโดเมน Unix, ไปป์และ FIFO พวกเขาทั้งหมดบัฟเฟอร์ข้อมูลที่ถูกส่งในหน่วยความจำที่ใช้ร่วมกันภายใต้ Linux? หากได้รับการยืนยันคำถามของฉันจะถูกแก้ไข อืม ... แก้ไขได้แล้วบางส่วน
Justin

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

อ่านความคิดเห็นอีกครั้งไม่แน่ใจว่าฉันชัดเจนที่นี่ ... แจ้งให้เราทราบหากยังมีสิ่งที่ไม่ชัดเจน
lgeorget

ความคิดเห็นของคุณชัดเจนสำหรับฉัน
Justin

7

มีการสนทนาที่ดีของที่นี่: 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_inatomiccall copy_user_genericซึ่งอยู่ในการประยุกต์ใช้ ASM หลายตัว


4

"FIFO" และ " named pipe" เป็นสิ่งเดียวกัน - แม้ว่ามันจะค่อนข้างแตกต่างจากวิธีที่เชลล์จัดการกับ "pipe" (|) ระหว่างสองคำสั่งบนบรรทัดคำสั่ง

ไปป์ที่มีชื่อ (FIFO) เป็น "ไฟล์" เดียวที่ใช้ร่วมกันโดยสองโปรแกรมโดยที่หนึ่งเขียนไปยังมันและอีกอ่านจากมัน ... ซ็อกเก็ตในมืออื่น ๆ คือ "การเชื่อมต่อ" ระหว่างสอง "ไฟล์" - ซึ่งอาจ ใช้เครือข่ายและอยู่ในคอมพิวเตอร์แยกต่างหาก - ที่หนึ่งโปรแกรมอ่าน / เขียนไปยัง "ไฟล์" หนึ่งและอีกโปรแกรมอ่าน / เขียนไปยังอีก ... ฉันไม่คิดว่าพวกเขาจะคล้ายกัน ... ในอีกทางหนึ่งทั้งสอง ซ็อกเก็ตและไพพ์ที่มีชื่อ - รวมถึงไฟล์อุปกรณ์ลิงก์สัญลักษณ์ - ทั้งหมดใช้ inodes และทั้งหมดใช้คุณสมบัติทั่วไปบางอย่าง (เช่นอ่านและเขียน)


1
ใช่ซ็อกเก็ตโดเมน Unix เป็นประเภทซ็อกเก็ตดังนั้นจึงเป็น API คล้ายกับซ็อกเก็ต API อื่น ๆ เช่น TCP หรือ UDP เป็นต้นอย่างไรก็ตามซ็อกเก็ตโดเมน Unix สามารถใช้เป็น IPC "ท้องถิ่น" เท่านั้น และวิธีการถ่ายโอนข้อมูลเป็นครั้งแรกในลักษณะแรกสวยมากเหมือน FIFO & ไปป์ ดังนั้นฉันคิดว่ามันเป็นไปได้ที่ API ของซ็อกเก็ตโดเมน Unix นั้นเป็นอีกหนึ่งการห่อหุ้มของการติดตั้งที่เหมือนกันดังนั้นเราจึงใช้มันราวกับว่ามันเป็นซ็อกเก็ต ฉันคิดว่าเป็นไปได้ว่าพวกเขาทั้งหมดมีส่วนร่วมภายในเดียวกันในเคอร์เนล ... ฉันต้องการยืนยันว่าเป็นจริงหรือไม่
Justin

1

ฉันไม่คิดอย่างนั้นจัสติน ถ้าฉันไม่เข้าใจผิดและฉันอาจเป็นเช่นนั้นฉันคิดว่า FIFO ใช้ไฟล์บนดิสก์และซ็อกเก็ต Unix Domain ใช้หน่วยความจำเคอร์เนล

นอกจากนี้ในฐานะผู้โพสต์ข้างต้นผู้ที่กล่าวว่าซ็อกเก็ตโดเมน Unix เป็นแบบสองทิศทางนั่นเป็นเพียงกรณีเมื่อใช้ซ็อกเก็ต SOCK_STREAM SOCK_DGRAM ซ็อกเก็ตโดเมน Unix คืออันที่จริงแล้วเป็นทิศทางเดียวและสามารถส่ง () จากรหัสที่เรียกว่า connect () ไปยังรหัสที่เรียกว่า bind ()

แน่นอนว่ารหัสที่เรียกว่าการเชื่อมต่อ () จะต้องเรียกการผูก () เพื่อสร้างเป็นจุดสิ้นสุดของตัวเอง แต่ไม่มีส่วนเกี่ยวข้องกับคำถามของคุณ


3
ยินดีต้อนรับสู่ StackExchange และขอขอบคุณสำหรับการโพสต์ ข้อสังเกตเล็กน้อย ... 1) หากคุณ "ผิดปกติ" อาจเป็นไปได้ว่าคุณควรตรวจสอบอีกครั้งก่อนตอบ; ไซต์นี้ไม่ใช่ฟอรัมหรือการแชท 2) ขอบคุณสำหรับความแม่นยำของคุณในซ็อกเก็ตที่มุ่งเน้นดาตาแกรม 3) ไม่จำเป็นต้องโพสต์สิ่งที่มี "ไม่มีอะไรให้ทำ" กับคำถาม :)
lgeorget

1

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**

FIFO เป็นแบบสองทิศทางหรือไม่
jhfrontz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.