Sự khéo léo chính xác của ống Unix là gì


52

Tôi đã nghe câu chuyện về cách Douglas Mcllroy nghĩ ra ý tưởng và cách Ken Thompson thực hiện nó trong một đêm.

Theo tôi hiểu, pipe là một cuộc gọi hệ thống chia sẻ một phần bộ nhớ giữa hai quá trình trong đó một quá trình ghi và các lần đọc khác.

Là một người không quen thuộc với các khái niệm hoặc nội bộ hệ điều hành, tôi đã tự hỏi chính xác "thiên tài" trong câu chuyện là gì? Có phải đó là ý tưởng của hai quá trình chia sẻ bộ nhớ? Hay là nó thực hiện? Hoặc cả hai?

PS: Tôi biết về tiện ích của đường ống hoặc cách sử dụng nó trong vỏ. Câu hỏi là về khái niệm và thực hiện|


4
Tôi đoán trong những ngày đầu, việc thúc đẩy mạnh mẽ việc thực hiện một cơ chế để soạn các ứng dụng là khá triệt để. Để làm như vậy, bạn cần có một khái niệm rõ ràng về việc tách giao diện khỏi thực hiện và nhận ra tiện ích của thành phần chức năng trong lập trình.
Chan-Ho Suh

4
Không chỉ vậy, các ứng dụng, trong khi chạy, có tay cầm đầu vào tiêu chuẩn và tay cầm đầu ra tiêu chuẩn và API hệ điều hành giống Unix có chức năng đọc / ghi để áp dụng cho các tay cầm này. Việc sử dụng thông minh một vài khái niệm trực giao và có khả năng cao (xử lý, đầu ra và đầu vào từ chúng) không chỉ dẫn đến các đường ống, mà còn dẫn đến các ổ cắm, tương tác giữa thiết bị-nhân vật và hàng tá thứ khác. Vì vậy, bây giờ chúng ta có các tệp xử lý tệp (đối với tty cung cấp đầu vào bàn phím và đầu ra văn bản), hãy soạn các ứng dụng để một ứng dụng trở thành tty của ứng dụng kia.
Warren P

6
@WarrenP Trên thực tế, Unix có đầu vào tiêu chuẩn và đầu ra tiêu chuẩn vì tòa nhà pipe()|nhà điều hành shell (ref: McIlroy ). Hoặc, như Voltaire có thể đã nói, " Nếu [stdio] không tồn tại, thì cần phải phát minh ra [nó]. " :-)
Ross Patterson

Không có thứ gọi là tay cầm tập tin, và tay cầm trong và ngoài cho đến khi SAU ống?
Warren P

4
@WarrenP: Nghe có vẻ như những gì Patterson đang nói là: đầu tiên có xử lý tệp. Sau đó, những người này đã đưa ra ý tưởng rằng mỗi chương trình xử lý đầu vào và xử lý đầu ra theo mặc định, sau đó cho phép các chương trình xâu chuỗi một cách tầm thường. Chúng được gọi là đầu vào / đầu ra "tiêu chuẩn".
Vịt Mooing

Câu trả lời:


109

Theo tôi hiểu, pipe là một cuộc gọi hệ thống chia sẻ một phần bộ nhớ giữa hai quá trình trong đó một quá trình ghi và các lần đọc khác.

Trên thực tế, không có bộ nhớ chia sẻ liên quan. Người đọc và người viết KHÔNG chia sẻ bất kỳ phần nào trong không gian địa chỉ của họ và họ không sử dụng bất kỳ đồng bộ hóa rõ ràng nào.

Các quy trình đọc và viết đang thực hiện readwritegọi hệ thống chính xác như chúng sẽ đọc nếu chúng đang đọc từ / ghi vào một tệp. RATNG là thiên tài ... sự đổi mới: khái niệm rằng giao tiếp và tập tin I / O liên kết (đơn giản) có thể được xử lý theo cùng một cách ... từ quan điểm của người lập trình ứng dụng và người dùng.

Khi đường ống đã được thiết lập, HĐH (không phải mã ứng dụng hoặc thư viện trong không gian người dùng) sẽ đảm nhiệm việc đệm và phối hợp. Minh bạch.


Ngược lại, trước khi phát minh ra khái niệm đường ống, nếu bạn cần xử lý "đường ống", thông thường bạn sẽ có một ứng dụng ghi đầu ra vào một tệp, và sau đó khi nó kết thúc, bạn sẽ chạy ứng dụng thứ hai để đọc từ tập tin.

Ngoài ra, nếu bạn muốn có một đường ống thực sự, bạn có thể mã cả hai ứng dụng để thiết lập phân đoạn bộ nhớ dùng chung (thực) và sử dụng các từ ngữ nghĩa (hoặc một cái gì đó) để phối hợp đọc / ghi. Phức tạp ... và hậu quả là không thường xuyên được thực hiện.


34
"RATNG là thiên tài ... sự đổi mới: khái niệm rằng giao tiếp và I / O tập tin có thể được xử lý theo cùng một cách" - chính xác là như vậy. Nó cho phép bạn có giao tiếp giữa các chương trình không bao giờ được thiết kế để có nó và thậm chí không (cần) biết những gì đang xảy ra.
Guntram Blohm hỗ trợ Monica

6
Cũng rất hữu ích khi lưu ý rằng lý do sử dụng tệp I / O cho IPC chủ yếu hữu ích vì Unix được thiết kế để xử lý văn bản - truyền dữ liệu văn bản từ chương trình này sang chương trình khác, cho phép bố cục tương đối không gây đau đớn, điều đó có nghĩa là toàn bộ hệ thống có thể được xây dựng từ tương đối đơn giản, các chương trình nhỏ truyền dữ liệu từ cái này sang cái khác trong chuỗi dài (có thể) các hoạt động đơn giản. Về cơ bản, điều đó có nghĩa là bạn có một ngôn ngữ tương đối linh hoạt để xử lý văn bản.
Luaan

1
Và do đó, "sự khéo léo của Unix Unix" là "sự khéo léo của Unix": tất cả i / o (bao gồm giao tiếp giữa các quá trình, các tệp tiêu chuẩn và phần còn lại của các đối tượng hệ thống tệp) được xử lý như các tệp.
Đánh dấu Hurd

Một đột quỵ khác của thiên tài là UNIX ủng hộ các cấu trúc tệp có thể đọc được của con người trong thời điểm mỗi byte được tính ...
EvertW

14

Theo tôi, thiên tài về ý tưởng "ống dẫn" là sự đơn giản trong sử dụng.

Bạn không phải thực hiện bất kỳ cuộc gọi hệ thống, phân bổ bộ nhớ, không có gì phức tạp cả. Trong shell, bạn sử dụng một ký tự duy nhất : |. Điều này mang lại sức mạnh phi thường trong sự kết hợp của các công cụ đơn giản (hoặc phức tạp) cho một nhiệm vụ nhất định.

Thực hiện một số công việc hàng ngày phổ biến như sắp xếp văn bản gọn gàng. Bạn có thể có một lệnh liệt kê một loạt các tên. (Ví dụ của tôi, tôi sẽ sử dụng một tệp chứa một loạt các tên, theo lịch trình của listofrandomnames.com.) Sử dụng các đường ống bạn có thể làm một cái gì đó như sau:

$ cat names.txt
Sally Weikel
Dana Penaflor
Christine Hook
Shaneka Flythe
Almeda Crook
Freddie Lindley
Hester Kersh
Wanda Ruse
Megan Mauzy
Samuel Mancha
Paris Phipps
Annika Accardo
Elena Nabors
Caroline Foti
Jude Nesby
Chase Gordy
Carmela Driggers
Marlin Ostendorf
Harrison Dauber
$ cat names.txt | awk '{print $2 ", " $1}' | sort | uniq | column -c 100
Accardo, Annika     Hook, Christine     Ostendorf, Marlin
Crook, Almeda       Kersh, Hester       Penaflor, Dana
Dauber, Harrison    Lindley, Freddie    Phipps, Paris
Driggers, Carmela   Mancha, Samuel      Ruse, Wanda
Flythe, Shaneka     Mauzy, Megan        Weikel, Sally
Foti, Caroline      Nabors, Elena
Gordy, Chase        Nesby, Jude

Đây chỉ là một ví dụ; Có hàng ngàn. Đối với một vài nhiệm vụ cụ thể khác được thực hiện dễ dàng hơn đáng kể bằng cách sử dụng các đường ống, hãy xem phần "Triết lý Unix" trên trang này .


Để nhấn mạnh câu trả lời này, hãy xem các slide từ 4 đến 9 của bài thuyết trình, "Tại sao Zsh mát hơn Shell của bạn".


Tôi biết rằng lệnh trên bao gồm một UUOC . Tôi để nó đứng vì nó là một trình giữ chỗ cho một lệnh tùy ý tạo ra văn bản.


3
Ghi chú nhỏ xíu : sort -ucó thể làm công việc sort | uniqnhanh hơn.
Iwillnotexist Idonotexist

cat names.txt | awk '{print $2 ", " $1}' | sort | uniq | column -c 100Bạn có thể quen với nó, nhưng tôi sẽ không gọi nó đơn giản chút nào. Đặc biệt là awkphần.
Federico Poloni

Các đường ống rất đơn giản. Tôi đã nói, "... sức mạnh phi thường trong sự kết hợp của các công cụ đơn giản (hoặc phức tạp) với một nhiệm vụ nhất định."
tự đại diện

5

Vì vậy, tôi đã cố gắng thực hiện một chút nghiên cứu về điều này bằng cách tìm kiếm các hướng dẫn sử dụng PDP-10 / TOPS-10 để tìm hiểu trạng thái của nghệ thuật trước các đường ống. Tôi đã tìm thấy điều này , nhưng TOPS-10 rất khó để google. Có một vài tài liệu tham khảo tốt về phát minh ra đường ống: một cuộc phỏng vấn với McIlroy , về lịch sử và tác động của UNIX .

Bạn phải đặt điều này vào bối cảnh lịch sử. Rất ít các công cụ hiện đại và tiện lợi mà chúng ta cho là đã tồn tại.

"Lúc đầu, Thompson thậm chí không lập trình trên PDP mà thay vào đó sử dụng một bộ macro cho trình biên dịch GEMAP trên máy GE-635." (29) Một băng giấy được tạo ra trên GE 635 và sau đó được thử nghiệm trên PDP-7 cho đến khi, theo Ritchie, "một hạt nhân Unix nguyên thủy, một trình soạn thảo, một trình biên dịch, một trình bao đơn giản (trình thông dịch lệnh) và một vài tiện ích (như các lệnh rm, cat, cp) của Unix đã được hoàn thành. điểm, hệ điều hành là tự hỗ trợ, các chương trình có thể được viết và kiểm tra mà không cần dùng đến băng giấy, và sự phát triển vẫn tiếp tục trên chính PDP-7. "

Một PDP-7 trông như thế này . Lưu ý thiếu màn hình tương tác hoặc đĩa cứng. "Hệ thống tập tin" sẽ được lưu trữ trên băng từ. Có tới 64kB bộ nhớ cho các chương trình và dữ liệu.

Trong môi trường đó, các lập trình viên có xu hướng giải quyết trực tiếp phần cứng, chẳng hạn như bằng cách phát lệnh để quay băng và xử lý từng ký tự một lần đọc trực tiếp từ giao diện băng. UNIX cung cấp các khái niệm trừu tượng về điều này, thay vì "đọc từ teletype" và "đọc từ băng" là các giao diện riêng biệt được kết hợp thành một, với sự bổ sung quan trọng của "đọc từ đầu ra của chương trình khác mà không lưu trữ một bản sao tạm thời trên đĩa hoặc băng ".

Đây là McIlroy về phát minh của grep. Tôi nghĩ rằng đây là một công việc tốt để tổng hợp số lượng công việc cần thiết trong môi trường tiền UNIX.

"Grep được phát minh cho tôi. Tôi đang tạo ra một chương trình đọc to văn bản thông qua bộ tổng hợp giọng nói. Khi tôi phát minh ra các quy tắc ngữ âm, tôi sẽ kiểm tra từ điển của Webster để biết các từ mà chúng có thể thất bại. Ví dụ, làm thế nào để bạn đối phó với máy đào ' ui ', được phát âm theo nhiều cách khác nhau:' trái cây ',' guile ',' guilty ',' anguish ',' intuit ',' beguine '? Tôi sẽ chia từ điển thành các phần phù hợp với bộ đệm hạn chế của ed và sử dụng một lệnh toàn cầu để chọn một danh sách. Tôi sẽ thu nhỏ danh sách này bằng cách quét liên tục với ed để xem mỗi quy tắc được đề xuất hoạt động như thế nào. "

"Quá trình này rất tẻ nhạt và lãng phí khủng khiếp, vì từ điển phải được tách ra (người ta không thể để lại một bản sao tách trên dòng). Sau đó, ed sao chép từng phần vào / tmp, quét hai lần để thực hiện lệnh g, và cuối cùng đã ném nó đi, điều này cũng mất thời gian. "

"Một buổi chiều, tôi hỏi Ken Thompson rằng anh ta có thể nhấc bộ nhận dạng biểu thức chính quy ra khỏi trình chỉnh sửa và tạo một chương trình một lượt để làm việc đó không. Anh ta nói có. Sáng hôm sau tôi thấy một ghi chú trong thư thông báo một chương trình có tên grep. Nó hoạt động như một bùa mê. Khi được hỏi cái tên ngộ nghĩnh đó có nghĩa là gì, Ken nói điều đó là hiển nhiên. Nó đại diện cho lệnh biên tập mà nó mô phỏng, g / re / p (in biểu thức chính quy toàn cầu). "

So sánh phần đầu tiên với cat names.txt | awk '{print $2 ", " $1}' | sort | uniq | column -c 100ví dụ. Nếu các tùy chọn của bạn là "xây dựng một dòng lệnh" so với "viết một chương trình cụ thể cho mục đích, bằng tay, trong trình biên dịch chương trình", thì đó là giá trị xây dựng dòng lệnh. Ngay cả khi phải mất vài giờ đọc hướng dẫn (giấy) để làm điều đó. Sau đó bạn có thể viết nó ra để tham khảo trong tương lai.


1

Thiên tài của ống là nó kết hợp ba ý tưởng quan trọng.

Đầu tiên, đường ống là một triển khai thực tế của "các thói quen chung", một thuật ngữ được đặt ra bởi Conway vào năm 1958, có triển vọng nhưng ít được sử dụng thực tế trước ống.

Thứ hai, bằng cách thực hiện các đường ống trong ngôn ngữ shell, Thompson et al đã phát minh ra 'ngôn ngữ keo' thực sự đầu tiên.

Hai điểm này cho phép các thành phần phần mềm có thể tái sử dụng được phát triển hiệu quả bằng ngôn ngữ được tối ưu hóa ở mức độ thấp, sau đó dán lại với nhau để tạo thành chức năng phức tạp hơn, lớn hơn nhiều. Họ gọi đây là 'Lập trình lớn'.

Thứ ba, việc thực hiện các đường ống sử dụng cùng các cuộc gọi hệ thống đã được sử dụng để truy cập tệp cho phép các chương trình được viết bằng các giao diện phổ quát. Điều này cho phép các giải pháp thực sự phổ biến cho các vấn đề phần mềm, có thể được sử dụng tương tác, sử dụng dữ liệu từ các tệp và là một phần của hệ thống phần mềm lớn hơn, tất cả mà không có một thay đổi nào đối với các thành phần phần mềm. Không biên dịch, không cấu hình, chỉ một vài lệnh shell đơn giản.

Nếu bạn quan tâm đến việc học tập, phần mềm UNIX ngày nay vẫn hữu dụng như 40 năm trước. Chúng tôi liên tục phát minh lại những thứ họ đã biết và xây dựng giải pháp cho. Và bước đột phá quan trọng là ống đơn giản. Sự đổi mới thực sự duy nhất sau đó là việc tạo ra internet vào những năm 80. Thật đáng ngạc nhiên, UNIX đã thực hiện việc triển khai nó bằng cách tạo một API riêng. Chúng tôi vẫn phải chịu hậu quả ... Ồ, vâng, có một cái gì đó với màn hình video và chuột đã trở nên phổ biến vào cuối những năm 80. Nhưng đó là cho WIMP.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.