POWERMAN
"In each of us sleeps a genius...
and his sleep gets deeper everyday."

Думаю, общей информации по Inferno уже достаточно, и можно перейти к главному вопросу: что из себя представляет Inferno изнутри, с точки зрения программиста? В чём заключается взаимодействие программиста со средой предоставляемой Inferno? Сколько нюансов поведения и разных видов сущностей должен держать в голове программист в Inferno?

Например, под линухом для эффективного и качественного программирования нужно держать в голове как минимум несколько очень толстых томов Стивенса, начиная с APUE (Advanced Programming in the UNIX Environment, Second Edition, 925 страниц, обошлась мне в $75+доставка с амазона). И слава Богу, что такая книга вообще есть в природе, без неё было бы совсем туго, кстати!

А всё потому, что под линухом мы имеем множество разных сущностей (файлы/каталоги, процессы, терминалы, сигналы, нити, пайпы, сообщения, семафоры, разделяемая память, сетевые сокеты, unix сокеты, псевдо-терминалы, etc.), и у каждой море нюансов поведения (блокирующий I/O, неблокирующий I/O, асинхронный I/O, мультиплексирование I/O, fcntl/ioctl, etc.) в разных условиях! Насколько я понимаю, под виндой ситуация ещё хуже т.к. плюс к примерно аналогичному зоопарку добавляется по несколько версий API, которые Microsoft называет "новыми революционными технологиями" и выпускает раз в 2-3 года (у Джоэля Спольски была хорошая статья на эту тему).

Так вот, в Inferno таких сущностей ровно ТРИ: нити, каналы и файлы. И нюансов поведения у них значительно меньше: файлы поддерживают исключительно блокирующий I/O без возможности мультиплексирования, каналы тоже блокирующие но их можно мультиплексировать, файлы все "обычные" и никаких fcntl/ioctl в природе нет, etc. Причём этих трёх сущностей хватает, чтобы покрыть практически всю ту функциональность, для которой в UNIX-системах развели этот зоопарк!

1-я сущность: процесс/нить.

В Inferno нет отличия между процессами и нитями. Изолирование и группирование нитей осуществляется через namespaces. Вот сравнительная таблица свойств процессов Inferno по сравнению с процессами линуха:

Linux Inferno
Open files + +
UID, GID, EUID, EGID + ?
Supplementary group IDs +
Process group ID + +
Session ID +
Controlling terminal +
SUID and SGID flags +
Current working dir + +
Root dir + +
umask +
Signal mask and dispositions +
The close-on-exec flag for open files +
Environment + +
Attached shared memory segments +
Memory mappings +
Resource limits +
File locks for open files +
Pending alarms +
Namespace +

Что касается UID/GID/EUID/EGID, то UID, теоретически, в Inferno есть. А практически его как бы и нет - разделение прав доступа к ресурсам обеспечивается сертификатами, протоколом Styx, и namespace… а имя юзера никакой роли в этом процессе не играет и используется, насколько я понимаю, исключительно для определения имени домашнего каталога. Возможно я что-то не уловил, но похоже что Inferno под типовые определения однопользовательской/многопользовательской системы просто не попадает, это нечто иное. :)

Для управления практически всеми (кроме текущего каталога) свойствами процесса Inferno служит один, довольно простой сискол pctl.

Процессы в Inferno можно: порождать (оператором spawn в Limbo), изменять их свойства (сисколом pctl), завершать (оператором exit в Limbo) и … и всё, в общем! По крайней мере в той части, которая касается API Inferno. В принципе кроме этого можно ещё оперировать процессами через файлы в каталоге /prog/, но это уже относится к файловому API.

2-я сущность: каналы.

С каналами всё ещё проще, чем с процессами:

  • их можно создавать (как переменные в Limbo типа chan of что-то)

  • можно удалять (когда переменная выходит из области видимости либо в неё присваивают nil)

  • можно с помощью операторов Limbo chan← и ←chan атомарно, в блокирующем режиме принимать/передавать данные между нитями

  • можно мультиплексировать ввод/вывод в каналы

Этой функциональности достаточно, чтобы заменить все виды синхронизации и IPC существующие в линухе.

3-я сущность: файлы/каталоги.

Работа с файлами в Inferno не намного проще, чем в линухе - за исключением не нужных fcntl и ioctl API практически идентичное: mount, bind, chdir, open, dup, read, stat, diropen, dirread, etc…

Жизнь, правда, заметно упрощается за счёт того, что весь I/O в файлы только блокирующий, и мультиплексирования тоже нет - если что-то из этого арсенала необходимо это решается выделением блокирующих задач в отдельные нити (что, кстати, стимулирует более продуманную архитектуру приложения).

В принципе в Inferno ещё есть такой рудимент как пайпы. Но, в отличие от линуха, где они используются как одно из основных средств IPC, в Inferno пайпы это что-то типа workaround-а для случая, когда кому-нить (например, библиотечной функции) нужен файловый дескриптор, а вам хочется вместо дескриптора реального файла подсунуть ей "виртуальный" дескриптор ведущий не в реальный файл, а в ваш код.

Ещё добавляется работа со специфичными фичами Inferno - namespaces, поддержка протокола Styx и его сертификаты, авторизация, аутентификация и шифрование. Но эта часть работы обычно выполняется админом в командной строке (или в sh-скрипте запускающем ваше приложение), и никак не усложняет программирование приложения.

И всё?

И всё! Всё остальное это голые вычисления - обсчитывание данных в переменных: поддержка разных форматов файлов, баз данных, сетевых протоколов, etc. Это всё прикладуха, и никак не усложняет среду в которой работают программы и не вводит новых сущностей.

Бонус.

На закуску я повторю список сущностей линуха и покажу чем все они заменяются в Inferno:

Linux Inferno
файлы/каталоги файлы/каталоги
процессы нити
терминалы -
сигналы каналы
нити нити
пайпы - (тот workaround не считается)
сообщения каналы
семафоры каналы
разделяемая память каналы
сетевые сокеты файлы
unix сокеты - (надеюсь, скоро здесь будут стоять "файлы")
псевдо-терминалы -