ท่อชื่ออะไร?


คำตอบ:


156

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

เช่นเดียวกับที่คุณมีเซิร์ฟเวอร์ที่รับฟังที่อยู่ IP / พอร์ตสำหรับคำขอที่เข้ามาเซิร์ฟเวอร์ยังสามารถตั้งค่าไปป์ที่มีชื่อซึ่งสามารถรับฟังคำขอได้ ไม่ว่าในกรณีใดกระบวนการไคลเอ็นต์ (หรือไลบรารีการเข้าถึง DB) ต้องทราบแอดเดรสเฉพาะ (หรือชื่อไปป์) เพื่อส่งคำขอ บ่อยครั้งที่ค่าเริ่มต้นมาตรฐานที่ใช้กันทั่วไปมีอยู่ (เช่นเดียวกับพอร์ต 80 สำหรับ HTTP เซิร์ฟเวอร์ SQL ใช้พอร์ต 1433 ใน TCP / IP \\. \ pipe \ sql \ query สำหรับไปป์ที่มีชื่อ)

ด้วยการตั้งค่าไปป์ที่มีชื่อเพิ่มเติมคุณสามารถมีเซิร์ฟเวอร์ DB หลายตัวที่ทำงานโดยแต่ละเซิร์ฟเวอร์จะมีตัวรับฟังคำขอของตัวเอง

ข้อดีของไปป์ที่มีชื่อคือโดยปกติแล้วจะเร็วกว่ามากและทำให้ทรัพยากรของเครือข่ายสแตก

- BTW ในโลกของ Windows คุณสามารถตั้งชื่อไปป์ไปยังเครื่องระยะไกลได้ - แต่ในกรณีนี้ไปป์ที่มีชื่อจะถูกขนส่งผ่าน TCP / IP ดังนั้นคุณจะสูญเสียประสิทธิภาพ ใช้ไปป์ที่มีชื่อสำหรับการสื่อสารภายในเครื่อง


1
ข้อเสียคืออะไร?
lindhe

2
@lindhe ไม่มีการทำงานอัตโนมัติในเครือข่าย โดยทั่วไปจะยากกว่าในการตั้งค่าในทางปฏิบัติ การนำไปใช้งานใน Windows แตกต่างจากระบบที่คล้าย Unix / Unix พวกเขาเจ๋ง แต่ฉันจะไม่รำคาญเว้นแต่จะต้องมีการแสดง
sudo

44

Unix และ Windows ต่างก็มีสิ่งที่เรียกว่า "Named ไปป์" แต่ทำงานต่างกัน ใน Unix ไปป์ที่มีชื่อคือถนนทางเดียวซึ่งโดยทั่วไปจะมีผู้อ่านเพียงคนเดียวและนักเขียนคนเดียว - นักเขียนเขียนและผู้อ่านอ่านคุณเข้าใจหรือไม่

ใน Windows สิ่งที่เรียกว่า "Named pipe" คืออ็อบเจ็กต์ IPC คล้ายกับซ็อกเก็ต TCP สิ่งต่างๆสามารถไหลได้ทั้งสองทางและมีข้อมูลเมตาบางอย่าง (คุณสามารถรับข้อมูลประจำตัวของสิ่งต่างๆได้จากอีกด้านหนึ่งเป็นต้น)

ท่อที่มีชื่อ Unix ปรากฏเป็นไฟล์พิเศษในระบบไฟล์และสามารถเข้าถึงได้ด้วยคำสั่ง IO ของไฟล์ปกติรวมถึงเชลล์ Windows ไม่ได้และจำเป็นต้องเปิดด้วยการเรียกระบบพิเศษ (หลังจากนั้นพวกเขาจะทำงานเหมือนที่จับ win32 ปกติ)

ยิ่งทำให้สับสนมากขึ้น Unix มีสิ่งที่เรียกว่า "Unix socket" หรือ AF_UNIX socket ซึ่งทำงานคล้ายกับ win32 "named pipe" มากกว่า (แต่ไม่เหมือน) ซึ่งเป็นแบบสองทิศทาง


23

Linux Pipes
First In First Out (FIFO) กลไกการสื่อสารระหว่างการเข้าถึง

ท่อที่ไม่มีชื่อ
ในบรรทัดคำสั่งแสดงด้วยเครื่องหมาย "|" ระหว่างสองคำสั่ง

ท่อที่มีชื่อ
ไฟล์พิเศษ FIFO เมื่อสร้างแล้วคุณสามารถใช้ไปป์ได้เช่นเดียวกับไฟล์ปกติ (เปิดปิดเขียนอ่าน ฯลฯ )

ในการสร้างไปป์ที่มีชื่อเรียกว่า "myPipe" จากบรรทัดคำสั่ง ( man page ):

mkfifo myPipe  

ในการสร้างไปป์ที่มีชื่อจาก c โดยที่ "pathname" คือชื่อที่คุณต้องการให้ไพพ์มีและ "โหมด" มีสิทธิ์ที่คุณต้องการให้ไพพ์มี ( man page ):

#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);

2
"คุณสามารถใช้ไปป์ได้เหมือนไฟล์ทั่วไป" - ไม่เป็นความจริงทั้งหมด คุณไม่สามารถtell()วางตำแหน่งหรือseek()ในท่อได้
nyov

19

อ้างอิงจากWikipedia :

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



7

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

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


6

นี่คือ exeprt จาก Technet (ไม่แน่ใจว่าทำไมคำตอบที่ทำเครื่องหมายไว้บอกว่า named ไปป์เร็วกว่า ??):

Pipes กับ TCP / IP Sockets

ในสภาพแวดล้อมเครือข่ายท้องถิ่น (LAN) ที่รวดเร็วซ็อกเก็ต Transmission Control Protocol / Internet Protocol (TCP / IP) และไคลเอนต์ Named Pipes สามารถเทียบเคียงกันได้ในเรื่องประสิทธิภาพ อย่างไรก็ตามความแตกต่างด้านประสิทธิภาพระหว่างไคลเอนต์ TCP / IP Sockets และไคลเอ็นต์ Named Pipes จะเห็นได้ชัดกับเครือข่ายที่ช้ากว่าเช่นในเครือข่ายบริเวณกว้าง (WAN) หรือเครือข่าย dial-up นี่เป็นเพราะกลไกการสื่อสารระหว่างกระบวนการ (IPC) ที่แตกต่างกันในการสื่อสารระหว่างเพื่อน

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

สิ่งสำคัญคือต้องชี้แจงว่าคุณกำลังพูดถึงท่อในพื้นที่หรือท่อเครือข่าย หากแอ็พพลิเคชันเซิร์ฟเวอร์กำลังทำงานภายในเครื่องบนคอมพิวเตอร์ที่กำลังเรียกใช้อินสแตนซ์ของ SQL Server โพรโทคอล Named Pipes แบบโลคัลเป็นตัวเลือก ท่อที่มีชื่อในเครื่องทำงานในโหมดเคอร์เนลและเร็วมาก

สำหรับ TCP / IP Sockets การส่งข้อมูลมีความคล่องตัวมากขึ้นและมีค่าใช้จ่ายน้อยลง การส่งข้อมูลยังสามารถใช้ประโยชน์จากกลไกการเพิ่มประสิทธิภาพ TCP / IP Sockets เช่นการกำหนดหน้าต่างการตอบรับล่าช้าและอื่น ๆ สิ่งนี้มีประโยชน์มากในเครือข่ายที่ทำงานช้า ความแตกต่างของประสิทธิภาพดังกล่าวอาจมีนัยสำคัญทั้งนี้ขึ้นอยู่กับประเภทของแอปพลิเคชัน

TCP / IP Sockets ยังรองรับคิวงานค้าง สิ่งนี้สามารถให้เอฟเฟกต์การเรียบที่ จำกัด เมื่อเทียบกับไปป์ที่มีชื่อซึ่งอาจทำให้เกิดข้อผิดพลาดเกี่ยวกับไพพ์ไม่ว่างเมื่อคุณพยายามเชื่อมต่อกับ SQL Server

โดยทั่วไปแล้ว TCP / IP เป็นที่ต้องการในเครือข่าย LAN, WAN หรือ dial-up ที่ช้าในขณะที่ไปป์ที่มีชื่ออาจเป็นตัวเลือกที่ดีกว่าเมื่อความเร็วเครือข่ายไม่ใช่ปัญหาเนื่องจากมีฟังก์ชันการทำงานที่มากขึ้นใช้งานง่ายและตัวเลือกการกำหนดค่า


5

การสื่อสารระหว่างกระบวนการ (ส่วนใหญ่) สำหรับแอปพลิเคชัน Windows คล้ายกับการใช้ซ็อกเก็ตเพื่อสื่อสารระหว่างแอปพลิเคชันใน Unix

MSDN


4
ท่อที่มีชื่อปรากฏใน V6 หรือ AT&T Unix ประมาณปี 2518
dmckee --- อดีตผู้ดูแลลูกแมว

ดู๊! ก่อนหน้า Microsoft เล็กน้อย เท่าที่ฉันรู้ว่าพวกเขาไม่ได้ใช้บ่อยในแอปพลิเคชัน Unix / Linux จริงหรือ?
Ken

ฉันใช้ไปป์ที่มีชื่อสำหรับตัวสร้างลายเซ็นแบบสุ่มของฉัน - เนื่องจากแอพเมลและ usenet คาดว่าไฟล์ชื่อ $ HOME / .signature จะมีลายเซ็นของคุณโปรแกรมของฉันจะสร้างลายเซ็นเป็นไปป์ที่มีชื่อและเขียนใบเสนอราคาแบบสุ่มลงไป
Paul Tomblin

3

ไปป์ที่มีชื่อในบริบท unix / linux สามารถใช้เพื่อสร้างเชลล์สองอันที่แตกต่างกันเพื่อสื่อสารเนื่องจากเชลล์ไม่สามารถแชร์อะไรกับอันอื่นได้

นอกจากนี้สคริปต์หนึ่งสร้างอินสแตนซ์สองครั้งในเชลล์เดียวกันไม่สามารถแชร์อะไรผ่านอินสแตนซ์ทั้งสองได้ ฉันพบการใช้สำหรับไพพ์ที่มีชื่อเมื่อเข้ารหัส daemon ที่มีฟังก์ชัน start () และ stop () และฉันต้องการใช้สคริปต์เดียวกันเพื่อดำเนินการสองแอ็คชัน

การไม่มีไปป์ที่ระบุชื่อ (หรือเซมาฟอร์ใด ๆ ) การเริ่มสคริปต์ในพื้นหลังไม่ใช่ปัญหา สิ่งนี้ก็คือเมื่อเสร็จสิ้นคุณจะไม่สามารถเข้าถึงอินสแตนซ์ในพื้นหลังได้

ดังนั้นเมื่อคุณต้องการส่งคำสั่งหยุดให้เขาคุณก็ทำไม่ได้: การเรียกใช้สคริปต์เดียวกันโดยไม่ตั้งชื่อไปป์และการเรียกใช้ฟังก์ชัน stop () จะไม่ทำอะไรเลยเนื่องจากคุณกำลังเรียกใช้อินสแตนซ์อื่นอยู่

วิธีแก้ปัญหาคือการใช้สองไปป์หนึ่ง READ และ WRITE อื่น ๆ เมื่อคุณเริ่ม daemon จากนั้นให้เขาฟังท่อ READ ในงานอื่น ๆ จากนั้นฟังก์ชัน Stop () จะมีคำสั่งที่จะเขียนข้อความในไพพ์ซึ่งจะถูกจัดการโดยสคริปต์ที่ทำงานอยู่เบื้องหลังซึ่งจะดำเนินการออกจาก 0 วิธีนี้อินสแตนซ์ที่สองของสคริปต์เดียวกันของเรามีเฉพาะในงานที่ต้องทำ: บอกให้อินสแตนซ์แรกหยุด

วิธีนี้หนึ่งและสคริปต์เดียวสามารถเริ่มและหยุดตัวเองได้

แน่นอนว่าคุณมีหลายวิธีที่จะทำได้โดยการสั่งการหยุดด้วยการสัมผัสเป็นต้น แต่อันนี้ดีและน่าสนใจในการเขียนโค้ด


1

ท่อที่มีชื่อเป็นระบบหน้าต่างสำหรับการสื่อสารระหว่างกระบวนการ ในกรณีของเซิร์ฟเวอร์ SQL หากเซิร์ฟเวอร์อยู่บนเครื่องเดียวกันกับไคลเอนต์คุณสามารถใช้ไปป์ที่มีชื่อเพื่อถ่ายโอนข้อมูลได้ซึ่งต่างจาก TCP / IP


ไม่ใช่ Windows เท่านั้นเนื่องจากคำตอบของคุณปรากฏขึ้น ดังที่คนอื่น ๆ ได้กล่าวไว้แล้วว่าไปป์ที่มีชื่อนั้นมีมาตั้งแต่ยุค 70 ใน UNIX โดยทั่วไปมีลักษณะเป็นไฟล์พิเศษ โหวตแล้ว แต่แก้ไขคำตอบของคุณ
Chris Charabaruk
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.