Как Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Ρ‹ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Ρ‹ Π² Unix

Как Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Ρ‹ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Ρ‹ Π² Unix
Π’ этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ описана рСализация ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ΠΎΠ² Π² ядрС Unix. Π― Π±Ρ‹Π» нСсколько Ρ€Π°Π·ΠΎΡ‡Π°Ρ€ΠΎΠ²Π°Π½, Ρ‡Ρ‚ΠΎ нСдавняя ΡΡ‚Π°Ρ‚ΡŒΡ ΠΏΠΎΠ΄ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ «Как Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Ρ‹ Π² Unix?Β» оказалась Π½Π΅ ΠΏΡ€ΠΎ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅Π΅ устройство. МнС стало интСрСсно, ΠΈ я зарылся Π² старыС источники, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π°ΠΉΡ‚ΠΈ ΠΎΡ‚Π²Π΅Ρ‚.

О Ρ‡Ρ‘ΠΌ Ρ€Π΅Ρ‡ΡŒ?

ΠšΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Ρ‹ β€” «вСроятно, самоС Π²Π°ΠΆΠ½ΠΎΠ΅ ΠΈΠ·ΠΎΠ±Ρ€Π΅Ρ‚Π΅Π½ΠΈΠ΅ Π² UnixΒ» β€” это ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‰Π°Ρ характСристика Π»Π΅ΠΆΠ°Ρ‰Π΅ΠΉ Π² основС Unix философии объСдинСния Π²ΠΎΠ΅Π΄ΠΈΠ½ΠΎ ΠΌΠ°Π»Π΅Π½ΡŒΠΊΠΈΡ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ, Π° Ρ‚Π°ΠΊΠΆΠ΅ знакомая надпись Π² ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строкС:

$ echo hello | wc -c
6

Π­Ρ‚Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ зависит ΠΎΡ‚ прСдоставляСмого ядром систСмного Π²Ρ‹Π·ΠΎΠ²Π° pipe, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ описан Π½Π° страницах Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ pipe(7) ΠΈ pipe(2):

ΠšΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Ρ‹ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°ΡŽΡ‚ ΠΎΠ΄Π½ΠΎΠ½Π°ΠΏΡ€Π°Π²Π»Π΅Π½Π½Ρ‹ΠΉ ΠΊΠ°Π½Π°Π» мСТпроцСссного взаимодСйствия. Π£ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π° Π΅ΡΡ‚ΡŒ Π²Ρ…ΠΎΠ΄ (write end) ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄ (read end). Π”Π°Π½Π½Ρ‹Π΅, записанныС Π²ΠΎ Π²Ρ…ΠΎΠ΄ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π°, ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ считаны Π½Π° Π²Ρ‹Ρ…ΠΎΠ΄Π΅.

ΠšΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ создаётся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π²Ρ‹Π·ΠΎΠ²Π° pipe(2), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π΄Π²Π° Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Ρ… дСскриптора: ΠΎΠ΄ΠΈΠ½ ссылаСтся Π½Π° Π²Ρ…ΠΎΠ΄ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π°, Π²Ρ‚ΠΎΡ€ΠΎΠΉ Π½Π° Π²Ρ‹Ρ…ΠΎΠ΄.

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ трассировки ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Π½Π½ΠΎΠΉ Π²Ρ‹ΡˆΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ Π΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€ΠΈΡ€ΡƒΡŽΡ‚ созданиС ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π° ΠΈ ΠΏΠΎΡ‚ΠΎΠΊ Π΄Π°Π½Π½Ρ‹Ρ… Ρ‡Π΅Ρ€Π΅Π· Π½Π΅Π³ΠΎ ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ процСсса Π² Π΄Ρ€ΡƒΠ³ΠΎΠΉ:

$ strace -qf -e execve,pipe,dup2,read,write 
    sh -c 'echo hello | wc -c'

execve("/bin/sh", ["sh", "-c", "echo hello | wc -c"], …)
pipe([3, 4])                            = 0
[pid 2604795] dup2(4, 1)                = 1
[pid 2604795] write(1, "hellon", 6)    = 6
[pid 2604796] dup2(3, 0)                = 0
[pid 2604796] execve("/usr/bin/wc", ["wc", "-c"], …)
[pid 2604796] read(0, "hellon", 16384) = 6
[pid 2604796] write(1, "6n", 2)        = 2

Π ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ процСсс Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ pipe(), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Ρ‘Π½Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Π΅ дСскрипторы. Один Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΉ процСсс записываСт Π² ΠΎΠ΄ΠΈΠ½ дСскриптор, Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ процСсс считываСт Ρ‚Π΅ ΠΆΠ΅ Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ дСскриптора. ΠžΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ dup2 Β«ΠΏΠ΅Ρ€Π΅ΠΈΠΌΠ΅Π½ΠΎΠ²Ρ‹Π²Π°Π΅Ρ‚Β» дСскрипторы 3 ΠΈ 4, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ΠΈ соотвСтствовали stdin ΠΈ stdout.

Π‘Π΅Π· ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ΠΎΠ² ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ΅ ΠΏΡ€ΠΈΡˆΠ»ΠΎΡΡŒ Π±Ρ‹ Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΎΠ΄Π½ΠΎΠ³ΠΎ процСсса Π² Ρ„Π°ΠΉΠ» ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π΅Π³ΠΎ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ процСссу, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ‚ΠΎΡ‚ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π» Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ· Ρ„Π°ΠΉΠ»Π°. Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ ΠΌΡ‹ Ρ‚Ρ€Π°Ρ‚ΠΈΠ»ΠΈ Π±Ρ‹ большС рСсурсов ΠΈ мСсто Π½Π° дискС. Однако ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Ρ‹ Ρ…ΠΎΡ€ΠΎΡˆΠΈ Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ использования Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ²:

Если процСсс пытаСтся ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ ΠΈΠ· пустого ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π°, Ρ‚ΠΎΠ³Π΄Π° read(2) Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° Π΄Π°Π½Π½Ρ‹Π΅ Π½Π΅ станут доступны. Если процСсс попытаСтся Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π² Π·Π°ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€, Ρ‚ΠΎΠ³Π΄Π° write(2) Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΈΠ· ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π° Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ считано достаточно Π΄Π°Π½Π½Ρ‹Ρ… для выполнСния записи.

Как ΠΈ POSIX-Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΠ΅, это Π²Π°ΠΆΠ½ΠΎΠ΅ свойство: запись Π² ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ Π²ΠΏΠ»ΠΎΡ‚ΡŒ Π΄ΠΎ PIPE_BUF Π±Π°ΠΉΡ‚ΠΎΠ² (ΠΊΠ°ΠΊ ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ 512) Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½ΠΎΠΉ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ процСссы ΠΌΠΎΠ³Π»ΠΈ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ с Π΄Ρ€ΡƒΠ³ΠΎΠΌ Ρ‡Π΅Ρ€Π΅Π· ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ Ρ‚Π°ΠΊ, ΠΊΠ°ΠΊ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹ (Π½Π΅ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΠ΅ Ρ‚Π°ΠΊΠΈΡ… Π³Π°Ρ€Π°Π½Ρ‚ΠΈΠΉ) Π½Π΅ ΠΌΠΎΠ³ΡƒΡ‚.

ΠŸΡ€ΠΈ использовании ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π° процСсс ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π² Π½Π΅Π³ΠΎ всС свои Π²Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ процСссу. Или процСссы ΠΌΠΎΠ³ΡƒΡ‚ Π΄Π΅ΠΉΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ Тёсткого распараллСливания, с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ внСшнСго сигнального ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° (Π²Ρ€ΠΎΠ΄Π΅ сСмафора) сообщая Π΄Ρ€ΡƒΠ³ Π΄Ρ€ΡƒΠ³Ρƒ ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ записи ΠΈΠ»ΠΈ чтСния. ΠšΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Ρ‹ ΠΈΠ·Π±Π°Π²Π»ΡΡŽΡ‚ нас ΠΎΡ‚ всСх этих Ρ…Π»ΠΎΠΏΠΎΡ‚.

Π§Ρ‚ΠΎ ΠΌΡ‹ ΠΈΡ‰Π΅ΠΌ?

Объясню Π½Π° ΠΏΠ°Π»ΡŒΡ†Π°Ρ…, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²Π°ΠΌ Π±Ρ‹Π»ΠΎ Π»Π΅Π³Ρ‡Π΅ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ, ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€. Π’Π°ΠΌ понадобится Π²Ρ‹Π΄Π΅Π»ΠΈΡ‚ΡŒ Π² памяти Π±ΡƒΡ„Π΅Ρ€ ΠΈ ΠΊΠ°ΠΊΠΎΠ΅-Ρ‚ΠΎ состояниС. ΠŸΠΎΠ½Π°Π΄ΠΎΠ±ΡΡ‚ΡΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ для добавлСния ΠΈ удалСния Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ· Π±ΡƒΡ„Π΅Ρ€Π°. ΠŸΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡ‚ΡΡ ΠΊΠ°ΠΊΠΎΠ΅-Ρ‚ΠΎ срСдство, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π² Ρ…ΠΎΠ΄Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ чтСния ΠΈ записи Π² Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Π΅ дСскрипторы. И понадобятся Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ описанноС Π²Ρ‹ΡˆΠ΅ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΡ‹ Π³ΠΎΡ‚ΠΎΠ²Ρ‹ Π΄ΠΎΠΏΡ€ΠΎΡΠΈΡ‚ΡŒ ΠΏΡ€ΠΈ ярком свСтС Π»Π°ΠΌΠΏ исходный ΠΊΠΎΠ΄ ядра, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€Π΄ΠΈΡ‚ΡŒ ΠΈΠ»ΠΈ ΠΎΠΏΡ€ΠΎΠ²Π΅Ρ€Π³Π½ΡƒΡ‚ΡŒ Π½Π°ΡˆΡƒ ΡΠΌΡƒΡ‚Π½ΡƒΡŽ ΠΌΡ‹ΡΠ»Π΅Π½Π½ΡƒΡŽ модСль. Но всСгда Π±ΡƒΠ΄ΡŒΡ‚Π΅ Π³ΠΎΡ‚ΠΎΠ²Ρ‹ ΠΊ нСоТиданностям.

Π“Π΄Π΅ ΠΌΡ‹ ΠΈΡ‰Π΅ΠΌ?

Π― Π½Π΅ знаю, Π³Π΄Π΅ Π»Π΅ΠΆΠΈΡ‚ ΠΌΠΎΠΉ экзСмпляр извСстной ΠΊΠ½ΠΈΠ³ΠΈ Β«Lions bookΒ« с исходным ΠΊΠΎΠ΄ΠΎΠΌ Unix 6, Π½ΠΎ благодаря The Unix Heritage Society ΠΌΠΎΠΆΠ½ΠΎ Π² ΠΎΠ½Π»Π°ΠΉΠ½Π΅ ΠΏΠΎΠΈΡΠΊΠ°Ρ‚ΡŒ Π² исходном ΠΊΠΎΠ΄Π΅ Π΅Ρ‰Ρ‘ Π±ΠΎΠ»Π΅Π΅ старых вСрсий Unix.

Π‘Π»ΡƒΠΆΠ΄Π°Π½ΠΈΠ΅ ΠΏΠΎ Π°Ρ€Ρ…ΠΈΠ²Π°ΠΌ TUHS сродни ΠΏΠΎΡΠ΅Ρ‰Π΅Π½ΠΈΡŽ музСя. ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π²Π·Π³Π»ΡΠ½ΡƒΡ‚ΡŒ Π½Π° Π½Π°ΡˆΡƒ ΠΎΠ±Ρ‰ΡƒΡŽ ΠΈΡΡ‚ΠΎΡ€ΠΈΡŽ, ΠΈ я ΠΈΡΠΏΡ‹Ρ‚Ρ‹Π²Π°ΡŽ ΡƒΠ²Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΊ ΠΌΠ½ΠΎΠ³ΠΎΠ»Π΅Ρ‚Π½ΠΈΠΌ усилиям ΠΏΠΎ Π²ΠΎΡΡΡ‚Π°Π½ΠΎΠ²Π»Π΅Π½ΠΈΡŽ всСх этих ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΎΠ² Π±ΠΈΡ‚ Π·Π° Π±ΠΈΡ‚ΠΎΠΌ со старых кассСт ΠΈ распСчаток. И остро осознаю Ρ‚Π΅ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π΅Ρ‰Ρ‘ ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‚.

Π£Π΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€ΠΈΠ² своё Π»ΡŽΠ±ΠΎΠΏΡ‹Ρ‚ΡΡ‚Π²ΠΎ Π² части Π΄Ρ€Π΅Π²Π½Π΅ΠΉ истории ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ΠΎΠ², для сравнСния ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π½Π° соврСмСнныС ядра.

ΠšΡΡ‚Π°Ρ‚ΠΈ, pipe являСтся систСмным Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ Π½ΠΎΠΌΠ΅Ρ€ 42 Π² Ρ‚Π°Π±Π»ΠΈΡ†Π΅ sysent[]. Π‘ΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅?

Π’Ρ€Π°Π΄ΠΈΡ†ΠΈΠΎΠ½Π½Ρ‹Π΅ ядра Unix (1970–1974)

Π― Π½Π΅ Π½Π°ΡˆΡ‘Π» Π½ΠΈΠΊΠ°ΠΊΠΈΡ… слСдов pipe(2) Π½ΠΈ Π² PDP-7 Unix (ΡΠ½Π²Π°Ρ€ΡŒ 1970-Π³ΠΎ), Π½ΠΈ Π² ΠΏΠ΅Ρ€Π²ΠΎΠΉ Ρ€Π΅Π΄Π°ΠΊΡ†ΠΈΠΈ Unix (Π½ΠΎΡΠ±Ρ€ΡŒ 1971-Π³ΠΎ), Π½ΠΈ Π² Π½Π΅ΠΏΠΎΠ»Π½ΠΎΠΌ исходном ΠΊΠΎΠ΄Π΅ Π²Ρ‚ΠΎΡ€ΠΎΠΉ Ρ€Π΅Π΄Π°ΠΊΡ†ΠΈΠΈ (июнь 1972-Π³ΠΎ).

TUHS ΡƒΡ‚Π²Π΅Ρ€ΠΆΠ΄Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Ρ‚Ρ€Π΅Ρ‚ΡŒΡ рСдакция Unix (Ρ„Π΅Π²Ρ€Π°Π»ΡŒ 1973-Π³ΠΎ) стала ΠΏΠ΅Ρ€Π²ΠΎΠΉ вСрсиСй с ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π°ΠΌΠΈ:

Π’Ρ€Π΅Ρ‚ΡŒΡ рСдакция Unix Π±Ρ‹Π»Π° послСднСй вСрсиСй с ядром, написанным Π½Π° ассСмблСрС, Π½ΠΎ ΠΏΡ€ΠΈ этом ΠΏΠ΅Ρ€Π²ΠΎΠΉ вСрсиСй с ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π°ΠΌΠΈ. Π’ Ρ‚Π΅Ρ‡Π΅Π½ΠΈΠ΅ 1973-Π³ΠΎ вСлись Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΏΠΎ ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΡŽ Ρ‚Ρ€Π΅Ρ‚ΡŒΠ΅ΠΉ Ρ€Π΅Π΄Π°ΠΊΡ†ΠΈΠΈ, ядро пСрСписали Π½Π° Π‘, ΠΈ Ρ‚Π°ΠΊ появилась чСтвёртая рСдакция Unix.

Один ΠΈΠ· Ρ‡ΠΈΡ‚Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π°ΡˆΡ‘Π» скан Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ Π”Π°Π³ ΠœΠ°ΠΊΠ˜Π»Ρ€ΠΎΠΉ ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠΈΠ» идСю «соСдинСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ ΠΏΠΎ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΡƒ садового шланга».

Как Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Ρ‹ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Ρ‹ Π² Unix
Π’ ΠΊΠ½ΠΈΠ³Π΅ Π‘Ρ€Π°ΠΉΠ°Π½Π° ΠšΠ΅Ρ€Π½ΠΈΠ³Π°Π½Π° Β«Unix: A History and a MemoirΒ», Π² истории появлСния ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ΠΎΠ² Ρ‚ΠΎΠΆΠ΅ упоминаСтся этот Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚: «… ΠΎΠ½ висСл Π½Π° стСнС Π² ΠΌΠΎΡ‘ΠΌ офисС Π² Bell Labs Π² Ρ‚Π΅Ρ‡Π΅Π½ΠΈΠ΅ 30 Π»Π΅Ρ‚Β». Π’ΠΎΡ‚ ΠΈΠ½Ρ‚Π΅Ρ€Π²ΡŒΡŽ с ΠœΠ°ΠΊΠ˜Π»Ρ€ΠΎΠ΅ΠΌ, ΠΈ Π΅Ρ‰Ρ‘ ΠΎΠ΄Π½Π° история ΠΈΠ· Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠœΠ°ΠΊΠ˜Π»Ρ€ΠΎΡ, написанной Π² 2014-ΠΌ:

Когда появилась Unix, ΠΌΠΎΡ‘ ΡƒΠ²Π»Π΅Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΠΎΡ€ΡƒΡ‚ΠΈΠ½Π°ΠΌΠΈ заставило мСня ΠΏΠΎΠΏΡ€ΠΎΡΠΈΡ‚ΡŒ Π°Π²Ρ‚ΠΎΡ€Π° ОБ, КСна Вомпсона, ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹ΠΌ, записанным Π² ΠΊΠ°ΠΊΠΎΠΉ-Ρ‚ΠΎ процСсс, ΠΈΠ΄Ρ‚ΠΈ Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π° устройство, Π½ΠΎ ΠΈ Π½Π° Π²Ρ‹Ρ…ΠΎΠ΄ ΠΊ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ процСссу. КСн Ρ€Π΅ΡˆΠΈΠ», Ρ‡Ρ‚ΠΎ это Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ. Однако, ΠΊΠ°ΠΊ минималист, ΠΎΠ½ Ρ…ΠΎΡ‚Π΅Π», Ρ‡Ρ‚ΠΎΠ±Ρ‹ каТдая систСмная функция ΠΈΠ³Ρ€Π°Π»Π° Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ Ρ€ΠΎΠ»ΡŒ. Π”Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π»ΠΈ прямая запись ΠΌΠ΅ΠΆΠ΄Ρƒ процСссами ΠΈΠΌΠ΅Π΅Ρ‚ большоС прСимущСство ΠΏΠΎ ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с записью Π² ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ»? И Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊΠΎΠ³Π΄Π° я внёс ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ΅ ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅ с броским Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ Β«ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Β» ΠΈ описаниСм синтаксиса взаимодСйствия процСссов, КСн, Π½Π°ΠΊΠΎΠ½Π΅Ρ†-Ρ‚ΠΎ, воскликнул: Β«Π― сдСлаю это!Β».

И сдСлал. Одним ΡΡƒΠ΄ΡŒΠ±ΠΎΠ½ΠΎΡΠ½Ρ‹ΠΌ Π²Π΅Ρ‡Π΅Ρ€ΠΎΠΌ КСн ΠΈΠ·ΠΌΠ΅Π½ΠΈΠ» ядро ΠΈ ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΡƒ, исправил нСсколько стандартных ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ, стандартизировав ΠΈΡ… ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρƒ принятия Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… (ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠΎΡΡ‚ΡƒΠΏΠ°Ρ‚ΡŒ ΠΈΠ· ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π°), Π° Ρ‚Π°ΠΊΠΆΠ΅ помСнял ΠΈΠΌΠ΅Π½Π° Ρ„Π°ΠΉΠ»ΠΎΠ². На ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ дСнь ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Ρ‹ Π½Π°Ρ‡Π°Π»ΠΈ ΠΎΡ‡Π΅Π½ΡŒ ΡˆΠΈΡ€ΠΎΠΊΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒ Π² прилоТСниях. К ΠΊΠΎΠ½Ρ†Ρƒ Π½Π΅Π΄Π΅Π»ΠΈ ΡΠ΅ΠΊΡ€Π΅Ρ‚Π°Ρ€ΡˆΠΈ с ΠΈΡ… ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ отправляли Π½Π° ΠΏΡ€ΠΈΠ½Ρ‚Π΅Ρ€ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Ρ‹ ΠΈΠ· тСкстовых Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€ΠΎΠ². Π§ΡƒΡ‚ΡŒ ΠΏΠΎΠ·Π΄Π½Π΅Π΅ КСн Π·Π°ΠΌΠ΅Π½ΠΈΠ» ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ API ΠΈ синтаксис для ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠΈ использования ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ΠΎΠ² Π½Π° Π±ΠΎΠ»Π΅Π΅ чистыС соглашСния, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ с Ρ‚Π΅Ρ… ΠΏΠΎΡ€ ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ.

К соТалСнию, исходный ΠΊΠΎΠ΄ ядра Ρ‚Ρ€Π΅Ρ‚ΡŒΠ΅ΠΉ Ρ€Π΅Π΄Π°ΠΊΡ†ΠΈΠΈ Unix утСрян. И хотя Ρƒ нас Π΅ΡΡ‚ΡŒ написанный Π½Π° Π‘ исходный ΠΊΠΎΠ΄ ядра Ρ‡Π΅Ρ‚Π²Ρ‘Ρ€Ρ‚ΠΎΠΉ Ρ€Π΅Π΄Π°ΠΊΡ†ΠΈΠΈ, Π²Ρ‹ΡˆΠ΅Π΄ΡˆΠ΅ΠΉ Π² ноябрС 1973-Π³ΠΎ, ΠΎΠ΄Π½Π°ΠΊΠΎ ΠΎΠ½Π° Π²Ρ‹ΡˆΠ»Π° Π·Π° нСсколько мСсяцСв Π΄ΠΎ ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ Ρ€Π΅Π»ΠΈΠ·Π° ΠΈ Π½Π΅ содСрТит Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ΠΎΠ². Π–Π°Π»ΡŒ, Ρ‡Ρ‚ΠΎ исходный ΠΊΠΎΠ΄ Π»Π΅Π³Π΅Π½Π΄Π°Ρ€Π½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Unix утСрян, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, навсСгда.

Π£ нас Π΅ΡΡ‚ΡŒ тСкст Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ ΠΏΠΎ pipe(2) ΠΈΠ· ΠΎΠ±ΠΎΠΈΡ… Ρ€Π΅Π»ΠΈΠ·ΠΎΠ², поэтому ΠΌΠΎΠΆΠ½ΠΎ Π½Π°Ρ‡Π°Ρ‚ΡŒ с поиска Π² Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ Ρ‚Ρ€Π΅Ρ‚ΡŒΠ΅ΠΉ Ρ€Π΅Π΄Π°ΠΊΡ†ΠΈΠΈ (ΠΏΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½Ρ‹ΠΌ словам, ΠΏΠΎΠ΄Ρ‡Ρ‘Ρ€ΠΊΠ½ΡƒΡ‚Ρ‹ΠΌ Β«Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽΒ», строка ΠΈΠ· Π»ΠΈΡ‚Π΅Ρ€Π°Π»ΠΎΠ² ^H, послС ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΈΠ΄Ρ‘Ρ‚ Π½ΠΈΠΆΠ½Π΅Π΅ ΠΏΠΎΠ΄Ρ‡Ρ‘Ρ€ΠΊΠΈΠ²Π°Π½ΠΈΠ΅!). Π­Ρ‚ΠΎΡ‚ ΠΏΡ€ΠΎΡ‚ΠΎ-pipe(2) написан Π½Π° ассСмблСрС ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΉ дСскриптор, Π½ΠΎ ΡƒΠΆΠ΅ прСдоставляСт ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΡƒΡŽ ΠΎΡΠ½ΠΎΠ²Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ:

БистСмный Π²Ρ‹Π·ΠΎΠ² pipe создаёт ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ Π²Π²ΠΎΠ΄Π° Π²Ρ‹Π²ΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ называСтся ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ΠΎΠΌ. Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹ΠΉ Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΉ дСскриптор ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ чтСния ΠΈ записи. Когда Π² ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ записываСтся, Ρ‚ΠΎ буфСризуСтся Π΄ΠΎ 504 Π±Π°ΠΉΡ‚ΠΎΠ² Π΄Π°Π½Π½Ρ‹Ρ…, послС Ρ‡Π΅Π³ΠΎ процСсс записи приостанавливаСтся. ΠŸΡ€ΠΈ Ρ‡Ρ‚Π΅Π½ΠΈΠΈ ΠΈΠ· ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π° Π±ΡƒΡ„Π΅Ρ€ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ Π·Π°Π±ΠΈΡ€Π°ΡŽΡ‚ΡΡ.

К ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌΡƒ Π³ΠΎΠ΄Ρƒ ядро Π±Ρ‹Π»ΠΎ пСрСписано Π½Π° Π‘, Π° pipe(2) Π² Ρ‡Π΅Ρ‚Π²Ρ‘Ρ€Ρ‚ΠΎΠΉ Ρ€Π΅Π΄Π°ΠΊΡ†ΠΈΠΈ ΠΎΠ±Ρ€Ρ‘Π» свой соврСмСнный ΠΎΠ±Π»ΠΈΠΊ с ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏΠΎΠΌ Β«pipe(fildes)Β»:

БистСмный Π²Ρ‹Π·ΠΎΠ² pipe создаёт ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ Π²Π²ΠΎΠ΄Π° Π²Ρ‹Π²ΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ называСтся ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ΠΎΠΌ. Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Π΅ дСскрипторы ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² опСрациях чтСния ΠΈ записи. Когда Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ записываСтся Π² ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€, Ρ‚ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ дСскриптор, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹ΠΉ Π² r1 (соотв. fildes[1]), Ρ‚ΠΎ буфСризуСтся Π΄ΠΎ 4096 Π±Π°ΠΉΡ‚ΠΎΠ² Π΄Π°Π½Π½Ρ‹Ρ…, послС Ρ‡Π΅Π³ΠΎ процСсс записи приостанавливаСтся. ΠŸΡ€ΠΈ Ρ‡Ρ‚Π΅Π½ΠΈΠΈ ΠΈΠ· ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π° дСскриптор, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹ΠΉ Π² r0 (соотв. fildes[0]), Π·Π°Π±ΠΈΡ€Π°Π΅Ρ‚ Π΄Π°Π½Π½Ρ‹Π΅.

ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ‚ΡΡ, Ρ‡Ρ‚ΠΎ послС опрСдСлСния ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π° Π΄Π²Π° (ΠΈΠ»ΠΈ Π±ΠΎΠ»Π΅Π΅) Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… процСсса (созданных ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌΠΈ Π²Ρ‹Π·ΠΎΠ²Π°ΠΌΠΈ fork) Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ· ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² read ΠΈ write.

Π’ ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ΅ Π΅ΡΡ‚ΡŒ синтаксис для опрСдСлСния Π»ΠΈΠ½Π΅ΠΉΠ½ΠΎΠ³ΠΎ массива процСссов, соСдинённых посрСдством ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π°.

Π’Ρ‹Π·ΠΎΠ²Ρ‹ Π½Π° Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ ΠΈΠ· пустого ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π° (Π½Π΅ содСрТащСго Π±ΡƒΡ„Π΅Ρ€ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…), ΠΈΠΌΠ΅ΡŽΡ‰Π΅Π³ΠΎ лишь ΠΎΠ΄ΠΈΠ½ ΠΊΠΎΠ½Π΅Ρ† (Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹ всС Π·Π°ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰ΠΈΠ΅ Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Π΅ дСскрипторы), Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ Β«ΠΊΠΎΠ½Π΅Ρ† Ρ„Π°ΠΉΠ»Π°Β». Π’Ρ‹Π·ΠΎΠ²Ρ‹ Π½Π° запись Π² Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎΠΉ ситуации ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΡƒΡŽΡ‚ΡΡ.

Бамая ранняя ΡΠΎΡ…Ρ€Π°Π½ΠΈΠ²ΡˆΠ°ΡΡΡ рСализация ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π° относится ΠΊ пятой Ρ€Π΅Π΄Π°ΠΊΡ†ΠΈΠΈ Unix (июнь 1974-Π³ΠΎ), Π½ΠΎ ΠΎΠ½Π° ΠΏΠΎΡ‡Ρ‚ΠΈ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½Π° Ρ‚ΠΎΠΉ, Ρ‡Ρ‚ΠΎ появилась Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ Ρ€Π΅Π»ΠΈΠ·Π΅. Π›ΠΈΡˆΡŒ добавились ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ ΠΏΡΡ‚ΡƒΡŽ Ρ€Π΅Π΄Π°ΠΊΡ†ΠΈΡŽ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΎΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ.

ШСстая рСдакция Unix (1975)

НачинаСм Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ исходный ΠΊΠΎΠ΄ Unix ΡˆΠ΅ΡΡ‚ΠΎΠΉ Ρ€Π΅Π΄Π°ΠΊΡ†ΠΈΠΈ (ΠΌΠ°ΠΉ 1975-Π³ΠΎ). Π’ΠΎ ΠΌΠ½ΠΎΠ³ΠΎΠΌ благодаря Lions Π½Π°ΠΉΡ‚ΠΈ Π΅Π³ΠΎ Π³ΠΎΡ€Π°Π·Π΄ΠΎ Π»Π΅Π³Ρ‡Π΅, Ρ‡Π΅ΠΌ исходники Π±ΠΎΠ»Π΅Π΅ Ρ€Π°Π½Π½ΠΈΡ… вСрсий:

МногиС Π³ΠΎΠ΄Ρ‹ ΠΊΠ½ΠΈΠ³Π° Lions Π±Ρ‹Π»Π° СдинствСнным Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ ΠΏΠΎ ядру Unix, доступным Π²Π½Π΅ стСн Bell Labs. Π₯отя лицСнзия ΡˆΠ΅ΡΡ‚ΠΎΠΉ Ρ€Π΅Π΄Π°ΠΊΡ†ΠΈΠΈ позволяла прСподаватСлям ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΅Ρ‘ исходный ΠΊΠΎΠ΄, ΠΎΠ΄Π½Π°ΠΊΠΎ лицСнзия сСдьмой Ρ€Π΅Π΄Π°ΠΊΡ†ΠΈΠΈ ΠΈΡΠΊΠ»ΡŽΡ‡ΠΈΠ»Π° эту Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ, поэтому ΠΊΠ½ΠΈΠ³Π° Ρ€Π°ΡΠΏΡ€ΠΎΡΡ‚Ρ€Π°Π½ΡΠ»Π°ΡΡŒ Π² Π²ΠΈΠ΄Π΅ Π½Π΅Π»Π΅Π³Π°Π»ΡŒΠ½Ρ‹Ρ… ΠΌΠ°ΡˆΠΈΠ½ΠΎΠΏΠΈΡΠ½Ρ‹Ρ… ΠΊΠΎΠΏΠΈΠΉ.

БСгодня ΠΌΠΎΠΆΠ½ΠΎ ΠΊΡƒΠΏΠΈΡ‚ΡŒ Ρ€Π΅ΠΏΡ€ΠΈΠ½Ρ‚Π½Ρ‹ΠΉ экзСмпляр ΠΊΠ½ΠΈΠ³ΠΈ, Π½Π° ΠΎΠ±Π»ΠΎΠΆΠΊΠ΅ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½Ρ‹ студСнты Ρƒ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ Π°ΠΏΠΏΠ°Ρ€Π°Ρ‚Π°. А благодаря Π£ΠΎΡ€Ρ€Π΅Π½Ρƒ Π’ΡƒΠΌΠΈ (ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ запустил ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ TUHS) Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡΠΊΠ°Ρ‡Π°Ρ‚ΡŒ PDF-Ρ„Π°ΠΉΠ» с исходным ΠΊΠΎΠ΄ΠΎΠΌ ΡˆΠ΅ΡΡ‚ΠΎΠΉ Ρ€Π΅Π΄Π°ΠΊΡ†ΠΈΠΈ. Π₯ΠΎΡ‡Ρƒ Π΄Π°Ρ‚ΡŒ Π²Π°ΠΌ прСдставлСниС, сколько сил ΡƒΡˆΠ»ΠΎ Π½Π° созданиС Ρ„Π°ΠΉΠ»Π°:

Π‘ΠΎΠ»ΡŒΡˆΠ΅ 15 Π»Π΅Ρ‚ Π½Π°Π·Π°Π΄ я Π½Π°Π±Ρ€Π°Π» копию исходного ΠΊΠΎΠ΄Π°, ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Π½Π½ΠΎΠ³ΠΎ Π² Lions, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΌΠ½Π΅ Π½Π΅ Π½Ρ€Π°Π²ΠΈΠ»ΠΎΡΡŒ качСство ΠΌΠΎΠ΅ΠΉ ΠΊΠΎΠΏΠΈΠΈ с нСизвСстного количСства Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΊΠΎΠΏΠΈΠΉ. TUHS Π΅Ρ‰Ρ‘ Π½Π΅ сущСствовало, ΠΈ Ρƒ мСня Π½Π΅ Π±Ρ‹Π»ΠΎ доступа ΠΊ старым исходникам. Но Π² 1988-ΠΌ я Π½Π°ΡˆΡ‘Π» ΡΡ‚Π°Ρ€ΡƒΡŽ Π»Π΅Π½Ρ‚Ρƒ с 9 Π΄ΠΎΡ€ΠΎΠΆΠΊΠ°ΠΌΠΈ, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π±Ρ‹Π»Π° рСзСрвная копия ΠΈΠ· ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π° PDP11. Π’Ρ€ΡƒΠ΄Π½ΠΎ Π±Ρ‹Π»ΠΎ ΠΏΠΎΠ½ΡΡ‚ΡŒ, Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π»ΠΈ ΠΎΠ½Π°, Π½ΠΎ Ρ‚Π°ΠΌ Π±Ρ‹Π»ΠΎ Π½Π΅ΠΏΠΎΠ²Ρ€Π΅ΠΆΠ΄Ρ‘Π½Π½ΠΎΠ΅ Π΄Π΅Ρ€Π΅Π²ΠΎ /usr/src/, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²ΠΎ Ρ„Π°ΠΉΠ»ΠΎΠ² Π±Ρ‹Π»ΠΈ ΠΏΠΎΠΌΠ΅Ρ‡Π΅Π½Ρ‹ 1979-ΠΌ Π³ΠΎΠ΄ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΡƒΠΆΠ΅ Ρ‚ΠΎΠ³Π΄Π° выглядСло Π΄Ρ€Π΅Π²Π½ΠΎΡΡ‚ΡŒΡŽ. Π­Ρ‚ΠΎ Π±Ρ‹Π»Π° сСдьмая рСдакция ΠΈΠ»ΠΈ Π΅Ρ‘ производная PWB, ΠΊΠ°ΠΊ я считал.

Π― взял Π½Π°Ρ…ΠΎΠ΄ΠΊΡƒ Π·Π° основу ΠΈ Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ ΠΎΡ‚Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π» исходники Π΄ΠΎ состояния ΡˆΠ΅ΡΡ‚ΠΎΠΉ Ρ€Π΅Π΄Π°ΠΊΡ†ΠΈΠΈ. Π§Π°ΡΡ‚ΡŒ ΠΊΠΎΠ΄Π° ΠΎΡΡ‚Π°Π»Π°ΡΡŒ Ρ‚Π°ΠΊΠΎΠΉ ΠΆΠ΅, Ρ‡Π°ΡΡ‚ΡŒ ΠΏΡ€ΠΈΡˆΠ»ΠΎΡΡŒ слСгка ΠΏΠΎΠ΄Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, помСняв соврСмСнный Ρ‚ΠΎΠΊΠ΅Π½ += Π½Π° ΡƒΡΡ‚Π°Ρ€Π΅Π²ΡˆΠΈΠΉ =+. Π§Ρ‚ΠΎ-Ρ‚ΠΎ просто ΡƒΠ΄Π°Π»ΠΈΠ», Π° Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ ΠΏΡ€ΠΈΡˆΠ»ΠΎΡΡŒ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ ΠΏΠ΅Ρ€Π΅ΠΏΠΈΡΠ°Ρ‚ΡŒ, Π½ΠΎ Π½Π΅ слишком ΠΌΠ½ΠΎΠ³ΠΎ.

И сСгодня ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π² ΠΎΠ½Π»Π°ΠΉΠ½Π΅ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ Π½Π° TUHS исходный ΠΊΠΎΠ΄ ΡˆΠ΅ΡΡ‚ΠΎΠΉ Ρ€Π΅Π΄Π°ΠΊΡ†ΠΈΠΈ ΠΈΠ· Π°Ρ€Ρ…ΠΈΠ²Π°, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠΈΠ» Ρ€ΡƒΠΊΡƒ ДСннис Π ΠΈΡ‡ΠΈ.

ΠšΡΡ‚Π°Ρ‚ΠΈ, Π½Π° ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ взгляд, Π³Π»Π°Π²Π½ΠΎΠΉ ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΡŒΡŽ Π‘-ΠΊΠΎΠ΄Π° Π΄ΠΎ ΠΏΠ΅Ρ€ΠΈΠΎΠ΄Π° ΠšΠ΅Ρ€Π½ΠΈΠ³Π°Π½Π° ΠΈ Π ΠΈΡ‡ΠΈ являСтся Π΅Π³ΠΎ ΠΊΡ€Π°Ρ‚ΠΊΠΎΡΡ‚ΡŒ. НС Ρ‚Π°ΠΊ часто ΠΌΠ½Π΅ удаётся Π²ΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Ρ‹ ΠΊΠΎΠ΄Π° Π±Π΅Π· ΠΎΠ±ΡˆΠΈΡ€Π½ΠΎΠ³ΠΎ рСдактирования, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ соотвСтствовал ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΡƒΠ·ΠΊΠΎΠΉ области отобраТСния Π½Π° ΠΌΠΎΡ‘ΠΌ сайтС.

Π’ Π½Π°Ρ‡Π°Π»Π΅ /usr/sys/ken/pipe.c Π΅ΡΡ‚ΡŒ ΠΏΠΎΡΡΠ½ΡΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ (ΠΈ Π΄Π°, Ρ‚Π°ΠΌ Π΅ΡΡ‚ΡŒ Π΅Ρ‰Ρ‘ /usr/sys/dmr):

/*
 * Max allowable buffering per pipe.
 * This is also the max size of the
 * file created to implement the pipe.
 * If this size is bigger than 4096,
 * pipes will be implemented in LARG
 * files, which is probably not good.
 */
#define    PIPSIZ    4096

Π Π°Π·ΠΌΠ΅Ρ€ Π±ΡƒΡ„Π΅Ρ€Π° Π½Π΅ мСнялся со Π²Ρ€Π΅ΠΌΡ‘Π½ Ρ‡Π΅Ρ‚Π²Ρ‘Ρ€Ρ‚ΠΎΠΉ Ρ€Π΅Π΄Π°ΠΊΡ†ΠΈΠΈ. Но здСсь ΠΌΡ‹ Π±Π΅Π·ΠΎ всякой ΠΏΡƒΠ±Π»ΠΈΡ‡Π½ΠΎΠΉ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ Π²ΠΈΠ΄ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΊΠΎΠ³Π΄Π°-Ρ‚ΠΎ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Ρ‹ использовали Ρ„Π°ΠΉΠ»Ρ‹ Π² качСствС запасного Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π°!

Π§Ρ‚ΠΎ касаСтся LARG-Ρ„Π°ΠΉΠ»ΠΎΠ², Ρ‚ΠΎ ΠΎΠ½ΠΈ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‚ inode-Ρ„Π»Π°Π³Ρƒ LARG, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Β«Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠΎΠΌ большой адрСсации» для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ косвСнных (indirect) Π±Π»ΠΎΠΊΠΎΠ² с Ρ†Π΅Π»ΡŒΡŽ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ Π±ΠΎΠ»Π΅Π΅ ΠΊΡ€ΡƒΠΏΠ½Ρ‹Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Ρ… систСм. Π Π°Π· КСн сказал, Ρ‡Ρ‚ΠΎ Π»ΡƒΡ‡ΡˆΠ΅ ΠΈΡ… Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ, Ρ‚ΠΎ я с Ρ€Π°Π΄ΠΎΡΡ‚ΡŒΡŽ ΠΏΠΎΠ²Π΅Ρ€ΡŽ Π΅ΠΌΡƒ Π½Π° слово.

Π’ΠΎΡ‚ настоящий систСмный Π²Ρ‹Π·ΠΎΠ² pipe:

/*
 * The sys-pipe entry.
 * Allocate an inode on the root device.
 * Allocate 2 file structures.
 * Put it all together with flags.
 */
pipe()
{
    register *ip, *rf, *wf;
    int r;

    ip = ialloc(rootdev);
    if(ip == NULL)
        return;
    rf = falloc();
    if(rf == NULL) {
        iput(ip);
        return;
    }
    r = u.u_ar0[R0];
    wf = falloc();
    if(wf == NULL) {
        rf->f_count = 0;
        u.u_ofile[r] = NULL;
        iput(ip);
        return;
    }
    u.u_ar0[R1] = u.u_ar0[R0]; /* wf's fd */
    u.u_ar0[R0] = r;           /* rf's fd */
    wf->f_flag = FWRITE|FPIPE;
    wf->f_inode = ip;
    rf->f_flag = FREAD|FPIPE;
    rf->f_inode = ip;
    ip->i_count = 2;
    ip->i_flag = IACC|IUPD;
    ip->i_mode = IALLOC;
}

Π’ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ ясно описано, Ρ‡Ρ‚ΠΎ Ρ‚ΡƒΡ‚ происходит. Но Ρ€Π°Π·ΠΎΠ±Ρ€Π°Ρ‚ΡŒΡΡ Π² ΠΊΠΎΠ΄Π΅ Π½Π΅ Ρ‚Π°ΠΊ просто, отчасти ΠΈΠ·-Π·Π° Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Β«struct user uΒ» ΠΈ рСгистров R0 ΠΈ R1 ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ систСмных Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ значСния.

ΠŸΠΎΠΏΡ€ΠΎΠ±ΡƒΠ΅ΠΌ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ialloc() Ρ€Π°Π·ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ Π½Π° дискС inode (индСксный дСскриптор), Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ falloc() β€” Ρ€Π°Π·ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ Π² памяти Π΄Π²Π° Ρ„Π°ΠΉΠ»Π°. Если всё ΠΏΡ€ΠΎΠΉΠ΄Ρ‘Ρ‚ Ρ…ΠΎΡ€ΠΎΡˆΠΎ, Ρ‚ΠΎ ΠΌΡ‹ Π·Π°Π΄Π°Π΄ΠΈΠΌ Ρ„Π»Π°Π³ΠΈ для опрСдСлСния этих Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΊΠ°ΠΊ Π΄Π²ΡƒΡ… ΠΊΠΎΠ½Ρ†ΠΎΠ² ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π°, ΡƒΠΊΠ°ΠΆΠ΅ΠΌ ΠΈΡ… Π² Ρ‚ΠΎΠΌ ΠΆΠ΅ inode (Ρ‡Π΅ΠΉ счётчик ссылок станСт Ρ€Π°Π²Π΅Π½ 2), ΠΈ ΠΏΠΎΠΌΠ΅Ρ‚ΠΈΠΌ inode ΠΊΠ°ΠΊ ΠΈΠ·ΠΌΠ΅Π½Ρ‘Π½Π½Ρ‹ΠΉ ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠΉΡΡ. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° обращСния ΠΊ iput() Π² ΠΎΡˆΠΈΠ±ΠΎΡ‡Π½Ρ‹Ρ… путях (error paths) для ΡƒΠΌΠ΅Π½ΡŒΡˆΠ΅Π½ΠΈΡ счётчика ссылок Π² Π½ΠΎΠ²ΠΎΠΌ inode.

pipe() Π΄ΠΎΠ»ΠΆΠ΅Π½ Ρ‡Π΅Ρ€Π΅Π· R0 ΠΈ R1 Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ Π½ΠΎΠΌΠ΅Ρ€Π° Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Ρ… дСскрипторов для чтСния ΠΈ записи. falloc() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Ρ„Π°ΠΉΠ»ΠΎΠ²ΡƒΡŽ структуру, Π½ΠΎ Ρ‚Π°ΠΊΠΆΠ΅ Β«Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚Β» Ρ‡Π΅Ρ€Π΅Π· u.u_ar0[R0] ΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΉ дСскриптор. Π’ΠΎ Π΅ΡΡ‚ΡŒ ΠΊΠΎΠ΄ сохраняСт Π² r Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΉ дСскриптор для чтСния ΠΈ присваиваСт дСскриптор для записи прямо ΠΈΠ· u.u_ar0[R0] послС Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π° falloc().

Π€Π»Π°Π³ FPIPE, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΡ‹ Π·Π°Π΄Π°Π»ΠΈ ΠΏΡ€ΠΈ создании ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π°, управляСт ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ rdwr() Π² sys2.c, Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π΅ΠΉ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹Π΅ ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π° I/O:

/*
 * common code for read and write calls:
 * check permissions, set base, count, and offset,
 * and switch out to readi, writei, or pipe code.
 */
rdwr(mode)
{
    register *fp, m;

    m = mode;
    fp = getf(u.u_ar0[R0]);
        /* … */

    if(fp->f_flag&FPIPE) {
        if(m==FREAD)
            readp(fp); else
            writep(fp);
    }
        /* … */
}

Π—Π°Ρ‚Π΅ΠΌ функция readp() Π² pipe.c считываСт Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ· ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π°. Но ΠΏΡ€ΠΎΡΠ»Π΅Π΄ΠΈΡ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Π»ΡƒΡ‡ΡˆΠ΅ начиная с writep(). ΠŸΠΎΠ²Ρ‚ΠΎΡ€ΡŽΡΡŒ, ΠΊΠΎΠ΄ услоТнился ΠΈΠ·-Π·Π° особСнностСй соглашСния ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ², Π½ΠΎ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ подробности ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ.

writep(fp)
{
    register *rp, *ip, c;

    rp = fp;
    ip = rp->f_inode;
    c = u.u_count;

loop:
    /* If all done, return. */

    plock(ip);
    if(c == 0) {
        prele(ip);
        u.u_count = 0;
        return;
    }

    /*
     * If there are not both read and write sides of the
     * pipe active, return error and signal too.
     */

    if(ip->i_count < 2) {
        prele(ip);
        u.u_error = EPIPE;
        psignal(u.u_procp, SIGPIPE);
        return;
    }

    /*
     * If the pipe is full, wait for reads to deplete
     * and truncate it.
     */

    if(ip->i_size1 == PIPSIZ) {
        ip->i_mode =| IWRITE;
        prele(ip);
        sleep(ip+1, PPIPE);
        goto loop;
    }

    /* Write what is possible and loop back. */

    u.u_offset[0] = 0;
    u.u_offset[1] = ip->i_size1;
    u.u_count = min(c, PIPSIZ-u.u_offset[1]);
    c =- u.u_count;
    writei(ip);
    prele(ip);
    if(ip->i_mode&IREAD) {
        ip->i_mode =& ~IREAD;
        wakeup(ip+2);
    }
    goto loop;
}

На Π²Ρ…ΠΎΠ΄ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π° ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π±Π°ΠΉΡ‚Ρ‹ u.u_count. Π‘Π½Π°Ρ‡Π°Π»Π° ΠΏΠΎΡ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ индСксный дСскриптор (см. Π½ΠΈΠΆΠ΅ plock/prele).

Π—Π°Ρ‚Π΅ΠΌ провСряСм счётчик ссылок inode. Пока ΠΎΠ±Π° ΠΊΠΎΠ½Ρ†Π° ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π° ΠΎΡΡ‚Π°ΡŽΡ‚ΡΡ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌΠΈ, счётчик Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π²Π΅Π½ 2. ΠœΡ‹ ΠΏΡ€ΠΈΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌ ΠΎΠ΄Π½Ρƒ ссылку (ΠΈΠ· rp->f_inode), Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ Ссли счётчик Π±ΡƒΠ΄Π΅Ρ‚ мСньшС 2, Ρ‚ΠΎ это Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ Ρ‡ΠΈΡ‚Π°ΡŽΡ‰ΠΈΠΉ процСсс Π·Π°ΠΊΡ€Ρ‹Π» свой ΠΊΠΎΠ½Π΅Ρ† ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π°. Π˜Π½Ρ‹ΠΌΠΈ словами, ΠΌΡ‹ пытаСмся ΠΏΠΈΡΠ°Ρ‚ΡŒ Π² Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΉ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€, Π° это являСтся ошибкой. Π’ΠΏΠ΅Ρ€Π²Ρ‹Π΅ ΠΊΠΎΠ΄ ошибки EPIPE ΠΈ сигнал SIGPIPE появились Π² ΡˆΠ΅ΡΡ‚ΠΎΠΉ Ρ€Π΅Π΄Π°ΠΊΡ†ΠΈΠΈ Unix.

Но Π΄Π°ΠΆΠ΅ Ссли ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚, ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½. Π’ этом случаС ΠΌΡ‹ снимаСм Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ ΠΈ ΠΈΠ΄Ρ‘ΠΌ ΡΠΏΠ°Ρ‚ΡŒ Π² Π½Π°Π΄Π΅ΠΆΠ΄Π΅, Ρ‡Ρ‚ΠΎ Π΄Ρ€ΡƒΠ³ΠΎΠΉ процСсс ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π΅Ρ‚ ΠΈΠ· ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π° ΠΈ освободит Π² Π½Ρ‘ΠΌ достаточно мСста. ΠŸΡ€ΠΎΡΠ½ΡƒΠ²ΡˆΠΈΡΡŒ, ΠΌΡ‹ возвращаСмся ΠΊ Π½Π°Ρ‡Π°Π»Ρƒ, ΠΎΠΏΡΡ‚ΡŒ вСшаСм Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ ΠΈ запускаСм Π½ΠΎΠ²Ρ‹ΠΉ Ρ†ΠΈΠΊΠ» записи.

Если Π² ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π΅ достаточно свободного мСста, Ρ‚ΠΎ ΠΌΡ‹ записываСм Π² Π½Π΅Π³ΠΎ Π΄Π°Π½Π½Ρ‹Π΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ writei(). ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ i_size1 Ρƒ inode’Π° (ΠΏΡ€ΠΈ пустом ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π²Π΅Π½ 0) ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° ΠΊΠΎΠ½Π΅Ρ† Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π² Π½Ρ‘ΠΌ ΡƒΠΆΠ΅ содСрТатся. Если мСста для записи достаточно, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ ΠΎΡ‚ i_size1 Π΄ΠΎ PIPESIZ. Π—Π°Ρ‚Π΅ΠΌ снимаСм Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ ΠΈ пытаСмся ΠΏΡ€ΠΎΠ±ΡƒΠ΄ΠΈΡ‚ΡŒ любой процСсс, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΆΠ΄Ρ‘Ρ‚ возмоТности ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ ΠΈΠ· ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π°. ВозвращаСмся ΠΊ Π½Π°Ρ‡Π°Π»Ρƒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ, ΡƒΠ΄Π°Π»ΠΎΡΡŒ Π»ΠΈ Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ Π±Π°ΠΉΡ‚ΠΎΠ², сколько Π½Π°ΠΌ Π±Ρ‹Π»ΠΎ Π½ΡƒΠΆΠ½ΠΎ. Если Π½Π΅ ΡƒΠ΄Π°Π»ΠΎΡΡŒ, Ρ‚ΠΎ Π½Π°Ρ‡ΠΈΠ½Π°Π΅ΠΌ Π½ΠΎΠ²Ρ‹ΠΉ Ρ†ΠΈΠΊΠ» записи.

ΠžΠ±Ρ‹Ρ‡Π½ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ i_mode Ρƒ inode’Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для хранСния Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΉ r, w ΠΈ x. Но Π² случаС с ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π°ΠΌΠΈ ΠΌΡ‹ сигнализируСм ΠΎΠ± ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠΈ ΠΊΠ°ΠΊΠΈΠΌ-Ρ‚ΠΎ процСссом записи ΠΈΠ»ΠΈ чтСния с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π±ΠΈΡ‚ΠΎΠ² IREAD ΠΈ IWRITE соотвСтствСнно. ΠŸΡ€ΠΎΡ†Π΅ΡΡ Π·Π°Π΄Π°Ρ‘Ρ‚ Ρ„Π»Π°Π³ ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ sleep(), ΠΈ оТидаСтся, Ρ‡Ρ‚ΠΎ Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΌ ΠΊΠ°ΠΊΠΎΠΉ-Ρ‚ΠΎ Π΄Ρ€ΡƒΠ³ΠΎΠΉ процСсс Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚ wakeup().

НастоящСС Π²ΠΎΠ»ΡˆΠ΅Π±ΡΡ‚Π²ΠΎ происходит Π² sleep() ΠΈ wakeup(). Они Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Ρ‹ Π² slp.c, источникС Π·Π½Π°ΠΌΠ΅Π½ΠΈΡ‚ΠΎΠ³ΠΎ коммСнтария Β«Π’Ρ‹ Π½Π΅ обязаны это ΠΏΠΎΠ½ΠΈΠΌΠ°Ρ‚ΡŒΒ» (You are not expected to understand this). К ΡΡ‡Π°ΡΡ‚ΡŒΡŽ, ΠΌΡ‹ Π½Π΅ обязаны ΠΏΠΎΠ½ΠΈΠΌΠ°Ρ‚ΡŒ ΠΊΠΎΠ΄, просто посмотрим Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ:

/*
 * Give up the processor till a wakeup occurs
 * on chan, at which time the process
 * enters the scheduling queue at priority pri.
 * The most important effect of pri is that when
 * pri<0 a signal cannot disturb the sleep;
 * if pri>=0 signals will be processed.
 * Callers of this routine must be prepared for
 * premature return, and check that the reason for
 * sleeping has gone away.
 */
sleep(chan, pri) /* … */

/*
 * Wake up all processes sleeping on chan.
 */
wakeup(chan) /* … */

ΠŸΡ€ΠΎΡ†Π΅ΡΡ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ sleep() для ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½ΠΎΠ³ΠΎ ΠΊΠ°Π½Π°Π»Π°, ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠ·Π΄Π½Π΅Π΅ Ρ€Π°Π·Π±ΡƒΠΆΠ΅Π½ Π΄Ρ€ΡƒΠ³ΠΈΠΌ процСссом, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚ wakeup() для Ρ‚ΠΎΠ³ΠΎ ΠΆΠ΅ ΠΊΠ°Π½Π°Π»Π°. writep() ΠΈ readp() ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½ΠΈΡ€ΡƒΡŽΡ‚ свои дСйствия посрСдством Ρ‚Π°ΠΊΠΈΡ… ΠΏΠ°Ρ€Π½Ρ‹Ρ… Π²Ρ‹Π·ΠΎΠ²ΠΎΠ². ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ pipe.c всСгда ΠΎΡ‚Π΄Π°Ρ‘Ρ‚ ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ PPIPE ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ sleep(), поэтому всС sleep() ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Ρ‚ΡŒΡΡ ΠΏΠΎ сигналу.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Ρƒ нас Π΅ΡΡ‚ΡŒ всё, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Ρ‚ΡŒΡΡ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ readp():

readp(fp)
int *fp;
{
    register *rp, *ip;

    rp = fp;
    ip = rp->f_inode;

loop:
    /* Very conservative locking. */

    plock(ip);

    /*
     * If the head (read) has caught up with
     * the tail (write), reset both to 0.
     */

    if(rp->f_offset[1] == ip->i_size1) {
        if(rp->f_offset[1] != 0) {
            rp->f_offset[1] = 0;
            ip->i_size1 = 0;
            if(ip->i_mode&IWRITE) {
                ip->i_mode =& ~IWRITE;
                wakeup(ip+1);
            }
        }

        /*
         * If there are not both reader and
         * writer active, return without
         * satisfying read.
         */

        prele(ip);
        if(ip->i_count < 2)
            return;
        ip->i_mode =| IREAD;
        sleep(ip+2, PPIPE);
        goto loop;
    }

    /* Read and return */

    u.u_offset[0] = 0;
    u.u_offset[1] = rp->f_offset[1];
    readi(ip);
    rp->f_offset[1] = u.u_offset[1];
    prele(ip);
}

Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π²Π°ΠΌ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΎΡ‰Π΅ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ эту Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ снизу Π²Π²Π΅Ρ€Ρ…. Π’Π΅Ρ‚ΠΊΠ° Β«read and returnΒ» ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ, ΠΊΠΎΠ³Π΄Π° Π² ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π΅ Π΅ΡΡ‚ΡŒ ΠΊΠ°ΠΊΠΈΠ΅-Ρ‚ΠΎ Π΄Π°Π½Π½Ρ‹Π΅. Π’ этом случаС ΠΌΡ‹ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ readi() считываСм ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ Π΄Π°Π½Π½Ρ‹Ρ…, сколько доступно начиная с Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ f_offset чтСния, Π° Π·Π°Ρ‚Π΅ΠΌ обновляСм Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ смСщСния.

ΠŸΡ€ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ Ρ‡Ρ‚Π΅Π½ΠΈΠΈ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ Π±ΡƒΠ΄Π΅Ρ‚ пустым, Ссли смСщСниС чтСния достигло значСния i_size1 Ρƒ inode’Π°. ΠœΡ‹ сбрасываСм ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ Π½Π° 0 ΠΈ пытаСмся ΠΏΡ€ΠΎΠ±ΡƒΠ΄ΠΈΡ‚ΡŒ любой процСсс, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ…ΠΎΡ‡Π΅Ρ‚ Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π² ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€. ΠœΡ‹ Π·Π½Π°Π΅ΠΌ, Ρ‡Ρ‚ΠΎ ΠΊΠΎΠ³Π΄Π° ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠ»ΠΎΠ½, writep() заснёт Π½Π° ip+1. А Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ, ΠΊΠΎΠ³Π΄Π° ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ пуст, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΡ€ΠΎΠ±ΡƒΠ΄ΠΈΡ‚ΡŒ Π΅Π³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ Π²ΠΎΠ·ΠΎΠ±Π½ΠΎΠ²ΠΈΠ» свой Ρ†ΠΈΠΊΠ» записи.

Если Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ Π½Π΅Ρ‡Π΅Π³ΠΎ, Ρ‚ΠΎ readp() ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°Π΄Π°Ρ‚ΡŒ Ρ„Π»Π°Π³ IREAD ΠΈ Π·Π°ΡΠ½ΡƒΡ‚ΡŒ Π½Π° ip+2. ΠœΡ‹ Π·Π½Π°Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Π΅Π³ΠΎ ΠΏΡ€ΠΎΠ±ΡƒΠ΄ΠΈΡ‚ writep(), ΠΊΠΎΠ³Π΄Π° Π·Π°ΠΏΠΈΡˆΠ΅Ρ‚ Π² ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ ΠΊΠ°ΠΊΠΈΠ΅-Π½ΠΈΠ±ΡƒΠ΄ΡŒ Π΄Π°Π½Π½Ρ‹Π΅.

ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ ΠΊ readi() ΠΈ writei() ΠΏΠΎΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠΎΠ½ΡΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ вмСсто ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² Ρ‡Π΅Ρ€Π΅Π· Β«uΒ» ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠ±Ρ€Π°Ρ‰Π°Ρ‚ΡŒΡΡ с Π½ΠΈΠΌΠΈ ΠΊΠ°ΠΊ с ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΌΠΈ функциями Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±Π΅Ρ€ΡƒΡ‚ Ρ„Π°ΠΉΠ», ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ, Π±ΡƒΡ„Π΅Ρ€ Π² памяти, ΠΈ ΠΏΠΎΠ΄ΡΡ‡ΠΈΡ‚Ρ‹Π²Π°ΡŽΡ‚ количСство Π±Π°ΠΉΡ‚ΠΎΠ² для чтСния ΠΈΠ»ΠΈ записи.

/*
 * Read the file corresponding to
 * the inode pointed at by the argument.
 * The actual read arguments are found
 * in the variables:
 *    u_base        core address for destination
 *    u_offset    byte offset in file
 *    u_count        number of bytes to read
 *    u_segflg    read to kernel/user
 */
readi(aip)
struct inode *aip;
/* … */

/*
 * Write the file corresponding to
 * the inode pointed at by the argument.
 * The actual write arguments are found
 * in the variables:
 *    u_base        core address for source
 *    u_offset    byte offset in file
 *    u_count        number of bytes to write
 *    u_segflg    write to kernel/user
 */
writei(aip)
struct inode *aip;
/* … */

Π§Ρ‚ΠΎ касаСтся «консСрвативной» Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ, Ρ‚ΠΎ readp() ΠΈ writep() Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‚ inode Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° Π½Π΅ Π·Π°ΠΊΠΎΠ½Ρ‡Π°Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΈΠ»ΠΈ Π½Π΅ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ (Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Π²Ρ‹Π·ΠΎΠ²ΡƒΡ‚ wakeup). plock() ΠΈ prele() Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ просто: с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ Π½Π°Π±ΠΎΡ€Π° Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² sleep ΠΈ wakeup ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ Π½Π°ΠΌ ΠΏΡ€ΠΎΠ±ΡƒΠΆΠ΄Π°Ρ‚ΡŒ любой процСсс, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ Π½ΡƒΠΆΠ½Π° Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ°, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΌΡ‹ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Ρ‚ΠΎ сняли:

/*
 * Lock a pipe.
 * If its already locked, set the WANT bit and sleep.
 */
plock(ip)
int *ip;
{
    register *rp;

    rp = ip;
    while(rp->i_flag&ILOCK) {
        rp->i_flag =| IWANT;
        sleep(rp, PPIPE);
    }
    rp->i_flag =| ILOCK;
}

/*
 * Unlock a pipe.
 * If WANT bit is on, wakeup.
 * This routine is also used to unlock inodes in general.
 */
prele(ip)
int *ip;
{
    register *rp;

    rp = ip;
    rp->i_flag =& ~ILOCK;
    if(rp->i_flag&IWANT) {
        rp->i_flag =& ~IWANT;
        wakeup(rp);
    }
}

Π‘Π½Π°Ρ‡Π°Π»Π° я Π½Π΅ ΠΌΠΎΠ³ ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΏΠΎΡ‡Π΅ΠΌΡƒ readp() Π½Π΅ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ prele(ip) Π΄ΠΎ Π²Ρ‹Π·ΠΎΠ²Π° wakeup(ip+1). ΠŸΠ΅Ρ€Π²ΠΎΠ΅, Ρ‡Ρ‚ΠΎ writep() Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Π² своём Ρ†ΠΈΠΊΠ»Π΅, это plock(ip), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ Π²Π·Π°ΠΈΠΌΠΎΠ±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ΅, Ссли readp() Π΅Ρ‰Ρ‘ Π½Π΅ снял свой Π±Π»ΠΎΠΊ, поэтому ΠΊΠΎΠ΄ ΠΊΠ°ΠΊΠΈΠΌ-Ρ‚ΠΎ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ Π΄ΠΎΠ»ΠΆΠ΅Π½ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ. Если ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π½Π° wakeup(), Ρ‚ΠΎ становится понятно, Ρ‡Ρ‚ΠΎ ΠΎΠ½ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎΠΌΠ΅Ρ‡Π°Π΅Ρ‚ спящий процСсс ΠΊΠ°ΠΊ Π³ΠΎΡ‚ΠΎΠ²Ρ‹ΠΉ ΠΊ исполнСнию, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π² Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΌ sched() Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ запустила Π΅Π³ΠΎ. Π’Π°ΠΊ Ρ‡Ρ‚ΠΎ readp() Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ wakeup(), снимаСт Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ, Π·Π°Π΄Π°Ρ‘Ρ‚ IREAD ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ sleep(ip+2)β€” всё это Π΄ΠΎ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ writep() возобновляСт Ρ†ΠΈΠΊΠ».

На этом описаниС ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ΠΎΠ² Π² ΡˆΠ΅ΡΡ‚ΠΎΠΉ Ρ€Π΅Π΄Π°ΠΊΡ†ΠΈΠΈ Π·Π°ΠΊΠΎΠ½Ρ‡Π΅Π½ΠΎ. ΠŸΡ€ΠΎΡΡ‚ΠΎΠΉ ΠΊΠΎΠ΄, Π΄Π°Π»Π΅ΠΊΠΎ ΠΈΠ΄ΡƒΡ‰ΠΈΠ΅ послСдствия.

БСдьмая рСдакция Unix (ΡΠ½Π²Π°Ρ€ΡŒ 1979-Π³ΠΎ) Π±Ρ‹Π»Π° Π½ΠΎΠ²Ρ‹ΠΌ основным Ρ€Π΅Π»ΠΈΠ·ΠΎΠΌ (спустя Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ Π³ΠΎΠ΄Π°), Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ появилось ΠΌΠ½ΠΎΠ³ΠΎ Π½ΠΎΠ²Ρ‹Ρ… ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΠΈ свойств ядра. Π’Π°ΠΊΠΆΠ΅ Π² Π½Ρ‘ΠΌ ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»ΠΈ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ измСнСния Π² связи с использованиСм привСдСния Ρ‚ΠΈΠΏΠΎΠ², union’ов ΠΈ Ρ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π° структуры. Однако ΠΊΠΎΠ΄ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ΠΎΠ² практичСски Π½Π΅ измСнился. МоТСм ΠΏΡ€ΠΎΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ эту Ρ€Π΅Π΄Π°ΠΊΡ†ΠΈΡŽ.

Xv6, простоС Unix-ΠΎΠ±Ρ€Π°Π·Π½ΠΎΠ΅ ядро

На созданиС ядра Xv6 повлияла ΡˆΠ΅ΡΡ‚Π°Ρ рСдакция Unix, ΠΎΠ΄Π½Π°ΠΊΠΎ ΠΎΠ½ΠΎ написано Π½Π° соврСмСнном Π‘, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π΅Π³ΠΎ запускали Π½Π° x86-процСссорах. Код Π»Π΅Π³ΠΊΠΎ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ, ΠΎΠ½ понятСн. К Ρ‚ΠΎΠΌΡƒ ΠΆΠ΅, Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ исходников Unix с TUHS, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ, ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ Π½Π° Ρ‡Ρ‘ΠΌ-Ρ‚ΠΎ Π΅Ρ‰Ρ‘ ΠΊΡ€ΠΎΠΌΠ΅ PDP 11/70. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ это ядро ΡˆΠΈΡ€ΠΎΠΊΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π² Π²ΡƒΠ·Π°Ρ… ΠΊΠ°ΠΊ ΡƒΡ‡Π΅Π±Π½Ρ‹ΠΉ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π» ΠΏΠΎ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΌ систСмам. Π˜ΡΡ…ΠΎΠ΄Π½ΠΈΠΊΠΈ Π»Π΅ΠΆΠ°Ρ‚ Π½Π° Github.

Π’ ΠΊΠΎΠ΄Π΅ содСрТится понятная ΠΈ продуманная рСализация pipe.c, подкрСплённая Π±ΡƒΡ„Π΅Ρ€ΠΎΠΌ Π² памяти вмСсто inode Π½Π° дискС. Π—Π΄Π΅ΡΡŒ я ΠΏΡ€ΠΈΠ²ΠΎΠΆΡƒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ «структурного ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π°Β» ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pipealloc():

#define PIPESIZE 512

struct pipe {
  struct spinlock lock;
  char data[PIPESIZE];
  uint nread;     // number of bytes read
  uint nwrite;    // number of bytes written
  int readopen;   // read fd is still open
  int writeopen;  // write fd is still open
};

int
pipealloc(struct file **f0, struct file **f1)
{
  struct pipe *p;

  p = 0;
  *f0 = *f1 = 0;
  if((*f0 = filealloc()) == 0 || (*f1 = filealloc()) == 0)
    goto bad;
  if((p = (struct pipe*)kalloc()) == 0)
    goto bad;
  p->readopen = 1;
  p->writeopen = 1;
  p->nwrite = 0;
  p->nread = 0;
  initlock(&p->lock, "pipe");
  (*f0)->type = FD_PIPE;
  (*f0)->readable = 1;
  (*f0)->writable = 0;
  (*f0)->pipe = p;
  (*f1)->type = FD_PIPE;
  (*f1)->readable = 0;
  (*f1)->writable = 1;
  (*f1)->pipe = p;
  return 0;

 bad:
  if(p)
    kfree((char*)p);
  if(*f0)
    fileclose(*f0);
  if(*f1)
    fileclose(*f1);
  return -1;
}

pipealloc() Π·Π°Π΄Π°Ρ‘Ρ‚ состояниС всС ΠΎΡΡ‚Π°Π»ΡŒΠ½ΠΎΠΉ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ, которая Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ Π² сСбя Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ piperead(), pipewrite() ΠΈ pipeclose(). ЀактичСский систСмный Π²Ρ‹Π·ΠΎΠ² sys_pipe являСтся ΠΎΠ±Ρ‘Ρ€Ρ‚ΠΊΠΎΠΉ, Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠΉ Π² sysfile.c. Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΡŽ ΠΏΡ€ΠΎΡ‡Π΅ΡΡ‚ΡŒ вСсь Π΅Π³ΠΎ ΠΊΠΎΠ΄. Π‘Π»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ исходника ΡˆΠ΅ΡΡ‚ΠΎΠΉ Ρ€Π΅Π΄Π°ΠΊΡ†ΠΈΠΈ, Π½ΠΎ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ Π³ΠΎΡ€Π°Π·Π΄ΠΎ Π»Π΅Π³Ρ‡Π΅ ΠΈ приятнСС.

Linux 0.01

МоТно Π½Π°ΠΉΡ‚ΠΈ исходный ΠΊΠΎΠ΄ Linux 0.01. Π‘ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΡƒΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΈΠ·ΡƒΡ‡ΠΈΡ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ΠΎΠ² Π² Π΅Π³ΠΎ fs/pipe.c. Π—Π΄Π΅ΡΡŒ для прСдставлСния ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ inode, Π½ΠΎ сам ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ написан Π½Π° соврСмСнном C. Если Π²Ρ‹ ΠΏΡ€ΠΎΠ΄Ρ€Π°Π»ΠΈΡΡŒ Ρ‡Π΅Ρ€Π΅Π· ΠΊΠΎΠ΄ ΡˆΠ΅ΡΡ‚ΠΎΠΉ Ρ€Π΅Π΄Π°ΠΊΡ†ΠΈΠΈ, Ρ‚ΠΎ здСсь Π²Ρ‹ Π½Π΅ испытаСтС трудностСй. Π’Π°ΠΊ выглядит функция write_pipe():

int write_pipe(struct m_inode * inode, char * buf, int count)
{
    char * b=buf;

    wake_up(&inode->i_wait);
    if (inode->i_count != 2) { /* no readers */
        current->signal |= (1<<(SIGPIPE-1));
        return -1;
    }
    while (count-->0) {
        while (PIPE_FULL(*inode)) {
            wake_up(&inode->i_wait);
            if (inode->i_count != 2) {
                current->signal |= (1<<(SIGPIPE-1));
                return b-buf;
            }
            sleep_on(&inode->i_wait);
        }
        ((char *)inode->i_size)[PIPE_HEAD(*inode)] =
            get_fs_byte(b++);
        INC_PIPE( PIPE_HEAD(*inode) );
        wake_up(&inode->i_wait);
    }
    wake_up(&inode->i_wait);
    return b-buf;
}

Π”Π°ΠΆΠ΅ Π½Π΅ глядя Π½Π° опрСдСлСния структур ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Ρ‚ΡŒΡΡ, ΠΊΠ°ΠΊ счётчик ссылок inode ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ, ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ Π»ΠΈ опСрация записи ΠΊ SIGPIPE. Помимо ΠΏΠΎΠ±Π°ΠΉΡ‚ΠΎΠ²ΠΎΠΉ Ρ€Π°Π±ΠΎΡ‚Ρ‹ эту Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π»Π΅Π³ΠΊΠΎ ΡΠΎΠΏΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ с Π²Ρ‹ΡˆΠ΅ΠΎΠΏΠΈΡΠ°Π½Π½Ρ‹ΠΌΠΈ идСями. Π”Π°ΠΆΠ΅ Π»ΠΎΠ³ΠΈΠΊΠ° sleep_on/wake_up Π½Π΅ выглядит Ρ‚Π°ΠΊΠΎΠΉ Ρ‡ΡƒΠΆΠ΅Ρ€ΠΎΠ΄Π½ΠΎΠΉ.

Π‘ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ядра Linux, FreeBSD, NetBSD, OpenBSD

Π― быстро пробСТался ΠΏΠΎ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ соврСмСнным ядрам. Ни Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΈΠ· Π½ΠΈΡ… ΡƒΠΆΠ΅ Π½Π΅Ρ‚ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ с использованиСм диска (Π½Π΅ ΡƒΠ΄ΠΈΠ²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ). Π’ Linux своя собствСнная рСализация. И хотя Ρ‚Ρ€ΠΈ соврСмСнных BSD-ядра содСрТат Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π½Π° основС ΠΊΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±Ρ‹Π» написан Π”ΠΆΠΎΠ½ΠΎΠΌ Дайсоном, Π·Π° ΠΏΡ€ΠΎΡˆΠ΅Π΄ΡˆΠΈΠ΅ Π³ΠΎΠ΄Ρ‹ ΠΎΠ½ΠΈ стали слишком сильно ΠΎΡ‚Π»ΠΈΡ‡Π°Ρ‚ΡŒΡΡ Π΄Ρ€ΡƒΠ³ ΠΎΡ‚ Π΄Ρ€ΡƒΠ³Π°.

Π§Ρ‚ΠΎΠ±Ρ‹ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ fs/pipe.c (Π½Π° Linux) ΠΈΠ»ΠΈ sys/kern/sys_pipe.c (Π½Π° *BSD), трСбуСтся настоящая самоотдача. БСгодня Π² ΠΊΠΎΠ΄Π΅ Π²Π°ΠΆΠ½Ρ‹ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° Ρ‚Π°ΠΊΠΈΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΊΠ°ΠΊ Π²Π΅ΠΊΡ‚ΠΎΡ€Π½Ρ‹Π΅ ΠΈ асинхронныС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π°. А подробности выдСлСния памяти, Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΠΊ ΠΈ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ ядра β€” всё это сильно разнится. Π­Ρ‚ΠΎ Π½Π΅ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π½ΡƒΠΆΠ½ΠΎ Π²ΡƒΠ·Π°ΠΌ для Π²Π²ΠΎΠ΄Π½ΠΎΠ³ΠΎ курса ΠΏΠΎ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΌ систСмам.

Π’ любом случаС, ΠΌΠ½Π΅ Π±Ρ‹Π»ΠΎ интСрСсно Ρ€Π°ΡΠΊΠΎΠΏΠ°Ρ‚ΡŒ нСсколько старинных ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½ΠΎΠ² (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ SIGPIPE ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ EPIPE ΠΏΡ€ΠΈ записи Π² Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΉ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€) Π²ΠΎ всСх этих, Ρ‚Π°ΠΊΠΈΡ… Ρ€Π°Π·Π½Ρ‹Ρ…, соврСмСнных ядрах. ВСроятно, я Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ ΡƒΠ²ΠΈΠΆΡƒ Π²ΠΆΠΈΠ²ΡƒΡŽ ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€ PDP-11, Π½ΠΎ Π΅Ρ‰Ρ‘ Π΅ΡΡ‚ΡŒ Ρ‡Π΅ΠΌΡƒ ΠΏΠΎΡƒΡ‡ΠΈΡ‚ΡŒΡΡ Π½Π° ΠΊΠΎΠ΄Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±Ρ‹Π» написан Π·Π° нСсколько Π»Π΅Ρ‚ Π΄ΠΎ ΠΌΠΎΠ΅Π³ΠΎ роТдСния.

Написанная Π”ΠΈΠ²ΠΈ ΠšΠ°ΠΏΡƒΡ€ΠΎΠΌ Π² 2011-ΠΌ Π³ΠΎΠ΄Ρƒ ΡΡ‚Π°Ρ‚ΡŒΡ Β«The Linux Kernel Implementation of Pipes and FIFOsΒ» прСдставляСт собой ΠΎΠ±Π·ΠΎΡ€, ΠΊΠ°ΠΊ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ (Π΄ΠΎ сих ΠΏΠΎΡ€) ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Ρ‹ Π² Linux. А Π½Π΅Π΄Π°Π²Π½ΠΈΠΉ ΠΊΠΎΠΌΠΌΠΈΡ‚ Π² Linux ΠΈΠ»Π»ΡŽΡΡ‚Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π½ΡƒΡŽ модСль взаимодСйствия, Ρ‡ΡŒΠΈ возмоТности ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ°ΡŽΡ‚ возмоТности Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ²; Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, насколько Π΄Π°Π»Π΅ΠΊΠΎ ΡƒΡˆΠ»ΠΈ ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Ρ‹ ΠΎΡ‚ Β«ΠΎΡ‡Π΅Π½ΡŒ консСрвативной Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈΒ» Π² ядрС Unix ΡˆΠ΅ΡΡ‚ΠΎΠΉ Ρ€Π΅Π΄Π°ΠΊΡ†ΠΈΠΈ.

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com