Bosh sahifa Wiki Pipe

Pipe

Pipe — bir processning chiqishini boshqa processning kirishiga uzatadigan kernel boshqaruvidagi byte oqimi. Pipe Unix va Linux tizimlarda processlararo aloqaning eng sodda mexanizmlaridan biri.

Anonymous pipe odatda related processlar, masalan parent va child orasida ishlaydi.

Shell’dagi | operatori bir nechta commandni pipelinega bog‘laydi.

Shell pipeline

Misol:

cat access.log | grep "500" | sort

Bu yerda:

  1. cat stdoutni pipe’ga yozadi.
  2. grep pipe’dan stdin orqali o‘qiydi.
  3. grep natijani keyingi pipe’ga yozadi.
  4. sort oqimni o‘qiydi.

Processlar bir vaqtda ishlashi mumkin.

Pipe yaratish

Operatsion tizim pipe() orqali ikki file descriptor beradi:

  • read end;
  • write end.

Parent fork() qilganda descriptorlar childga meros bo‘ladi.

Keraksiz uchlar yopiladi. Aks holda EOF kelmasligi mumkin.

Bir yo‘nalish

Klassik anonymous pipe bir yo‘nalishli.

Ikki tomonlama aloqa uchun:

ishlatiladi.

Ba’zi OS “pipe” atamasida ikki yo‘nalishli implementatsiya berishi mumkin, portable kod klassik modelga tayanadi.

Byte stream

Pipe xabar chegarasini saqlamaydi.

Writer:

"abc"
"def"

deb ikki marta yozsa, reader:

"abcdef"

yoki bo‘laklarda o‘qishi mumkin.

Protocol delimiter, fixed length yoki length prefix ishlatadi.

Atomic write

Ma’lum kichik hajmgacha pipe write atomik bo‘lishi kafolatlanadi. POSIXda bu chegara PIPE_BUF bilan bog‘liq.

Ikki writer kichik yozuv yuborsa, ularning baytlari aralashmasligi kerak.

Katta write qismlarga bo‘linib, boshqa writer bilan aralashishi mumkin.

Buffer

Pipe kernel bufferga ega.

Writer bufferga yozadi, reader o‘qib bo‘shatadi.

Buffer to‘lsa blocking writer kutadi.

Reader sekin bo‘lsa backpressure avtomatik yuz beradi.

Blocking read

Pipe bo‘sh, ammo write end ochiq bo‘lsa reader kutadi.

Barcha write descriptorlar yopilsa, reader EOF oladi.

Bir process keraksiz write endni ochiq qoldirsa, consumer cheksiz kutishi mumkin.

Broken pipe

Reader barcha read endlarni yopsa, writer pipe’ga yozolmaydi.

Unixda writer SIGPIPE signal olishi yoki EPIPE xatosi qaytishi mumkin.

Dastur signal va xatoni boshqaradi.

Exit status

Shell pipeline’da qaysi command exit statusi umumiy natija bo‘lishi shell siyosatiga bog‘liq.

Ko‘pincha oxirgi command statusi olinadi.

pipefail yoqilsa, oldingi command xatosi ham pipeline’ni failure qiladi.

Bu deployment va backup scriptlarda muhim.

Standard stream

Shell pipe odatda stdoutni keyingi stdin’ga bog‘laydi.

stderr alohida terminalga chiqadi.

stderrni ham pipe’ga berish uchun shell redirection ishlatiladi.

Stdout va stderr birlashtirilsa, yozuv tartibi buffering sabab o‘zgarishi mumkin.

Buffering

Dastur stdout terminalga ulanganida line-buffered, pipe’ga ulanganida block-buffered ishlashi mumkin.

Natijada pipeline’da output kech ko‘rinadi.

Dastur flush qilishi yoki unbuffered rejim ishlatishi mumkin.

tee

tee stdin’ni faylga va stdoutga bir vaqtda yozadi.

Misol:

command | tee output.log | next-command

Pipeline kuzatuvi va arxiv uchun qulay.

Subprocess

Dasturlash tilida child process stdin, stdout va stderr pipe orqali boshqariladi.

Parent:

  • commandga input yuboradi;
  • output oladi;
  • error oladi;
  • exit status kutadi.

Agar parent stdoutni o‘qimasdan child tugashini kutsa, pipe buffer to‘lib deadlock bo‘lishi mumkin.

Pipe deadlock

Child ko‘p stdout va stderr yozadi. Parent faqat stdoutni o‘qiydi.

stderr buffer to‘ladi, child bloklanadi. Parent child tugashini kutadi.

Ikki oqim parallel o‘qiladi yoki birlashtiriladi.

Non-blocking pipe

Descriptor non-blocking rejimga o‘tkazilishi mumkin.

Data yo‘q yoki buffer to‘la bo‘lsa EAGAIN qaytadi.

Event loop pipe’ni poll yoki epoll bilan kuzatadi.

Pipe va FIFO

Anonymous pipe filesystem nomiga ega emas va related processlar orqali descriptor merosiga tayanadi.

FIFO named pipe bo‘lib, mustaqil processlar path orqali ochadi.

Data xususiyati ikkalasida ham byte streamga o‘xshash.

Pipe va socket

Unix socket:

  • ikki yo‘nalish;
  • bir nechta client;
  • message mode;
  • credential;
  • file descriptor passing

imkoniyatlariga ega.

Pipe sodda producer-consumer oqimi uchun yengil.

Xavfsizlik

Pipe descriptorini faqat meros olgan yoki boshqa IPC orqali qabul qilgan process ishlata oladi.

Child processga keraksiz descriptorlarni yopmaslik ma’lumot sizishi yoki lifecycle muammosiga olib keladi.

close-on-exec flag yangi executable’ga descriptor o‘tishini cheklaydi.

Diagnostika

Pipe muammosida:

  • read va write descriptor;
  • qaysi process ochiq ushlab turibdi;
  • EOF;
  • buffer;
  • blocked syscall;
  • SIGPIPE;
  • stdout/stderr;
  • buffering;
  • exit status;
  • pipefail

tekshiriladi.

strace read va write qayerda bloklanganini ko‘rsatishi mumkin.

Pipeline performance

Pipeline processlari bir vaqtda ishlagani sababli umumiy tezlik eng sekin bosqich bilan cheklanadi.

Agar producer juda tez bo‘lsa, pipe buffer to‘ladi va producer bloklanadi. Bu tabiiy flow control hisoblanadi.

Katta data uchun keraksiz cat, format conversion va ko‘p process yaratish overhead qo‘shishi mumkin. Pipeline bosqichlari profiling orqali baholanadi.

Binary data

Pipe binary baytlarni ham tashiydi. Matn delimiteriga tayangan vosita nol bayt yoki encoding bilan noto‘g‘ri ishlashi mumkin. Binary protocol aniq length va format ishlatadi.

Pipeline yakunlanishi

Parent process barcha child processlarning exit statusini yig‘ishi kerak. Faqat output EOF bo‘lishi command muvaffaqiyatli tugaganini anglatmaydi; producer xato bilan tugagan bo‘lishi mumkin.

Bog‘liq tushunchalar

IPC, File descriptor, Standard input, Standard output, FIFO, Shell pipeline, Buffer, SIGPIPE, Subprocess