I think that general information on
Inferno is already enough, and you can go to the main question: what is Inferno from the inside, from the point of view of a programmer? What is the interaction of the programmer with the environment provided by Inferno? How many nuances of behavior and different types of entities does a programmer in Inferno
have in mind ?
For example, for linux, for effective and high-quality programming, you need to keep at least some very thick Stevens volumes in your head, starting with APUE (Advanced Programming in the UNIX Environment, Second Edition, 925 pages, cost me $ 75 + shipping from Amazon). And thank God that such a book in general is in nature, without it it would be very tight, by the way!
And all because under the linux we have a lot of different entities (files / directories, processes, terminals, signals, threads, pipes, messages, semaphores, shared memory, network sockets, unix sockets, pseudo-terminals, etc.), and each sea of ​​nuances of behavior (blocking I / O, non-blocking I / O, asynchronous I / O, multiplexing I / O, fcntl / ioctl, etc.) in different conditions! As far as I understand, under Windows the situation is even worse. Plus, an approximately similar zoo is added along with several API versions, which Microsoft calls “new revolutionary technologies” and releases once every 2-3 years (
Joel Spolsky had a good article on this topic).
So, in Inferno such entities are exactly THREE:
threads ,
channels and
files . They have significantly fewer behavioral nuances: the files only support blocking I / O without the possibility of multiplexing, the channels are also blocking, but they can be multiplexed, the files are all “normal” and there are no fcntl / ioctl in nature, etc. Moreover, these three entities are enough to cover almost all the functionality for which this zoo was built on UNIX systems!
')
1st entity: process / thread
There is no difference between processes and threads in Inferno. Isolation and grouping of threads is done through namespaces. Here is a comparative table of the properties of Inferno processes compared to linux processes:
| 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 | + | |
Close-on-exec flag for open files | + | |
Environment | + | + |
Attached shared memory segments | + | |
Memory mappings | + | |
Resource limits | + | |
File locks for open files | + | |
Pending alarms | + | |
Namespace | | + |
As for the UID / GID / EUID / EGID, the UID is, in theory, in Inferno. But it’s almost as if there isn’t - the separation of access rights to resources is provided by certificates, Styx protocol, and namespace ... and the user’s name doesn’t play any role in this process and is used, as far as I understand, solely to determine the name of the home directory. Maybe I didn’t catch something, but it seems that Inferno doesn’t fit the typical definitions of a single-user / multi-user system, it’s something else. :)
Update: I figured out this issue, see the article
"And yet it is multiplayer!" .
To control virtually all (except the current directory) properties of the Inferno process, one is used, a rather simple
pctl (2) syskol .
Processes in Inferno can be: spawned (by the spawn operator in Limbo), change their properties (with the pctl siscol), terminate (by the exit operator in Limbo) and ... and that’s all! At least in that part which concerns API Inferno. In principle, besides this, you can still operate with processes through files in the
/prog/
directory, but this already applies to the file API.
2nd entity: channels
With channels it is still easier than with processes:
- they can be created (as variables in Limbo of the chan of something type)
- can be deleted (when a variable goes out of scope or is assigned nil)
- You can use the Limbo chan <- and <-chan atomically operators to receive / transfer data between threads in blocking mode
- can multiplex input / output channels
This functionality is enough to replace all types of synchronization and IPC existing in Linux.
3rd entity: files / directories
Working with files in Inferno is not much easier than in linux - except for unnecessary fcntl and ioctl APIs are almost identical: mount, bind, chdir, open, dup, read, stat, diropen, dirread, etc ...
Life, however, is considerably simplified due to the fact that all I / O in the files is only blocking, and there is no multiplexing either - if something from this arsenal is necessary, it is solved by separating blocking tasks into separate threads (which, by the way, stimulates a more thoughtful architecture). applications).
In principle, in Inferno there is still such a rudiment as pipe. But, unlike linuch, where they are used as one of the main IPC tools, inferno pipe is something like workaround for the case when someone (for example, a library function) needs a file descriptor instead of descriptor To send a real file to it, the “virtual” descriptor of the presenter is not in the real file, but in your code.
It also adds work with specific features of Inferno - namespaces, support for the Styx protocol and its certificates, authorization, authentication and encryption. But this part of the work is usually performed by the administrator in the command line (or in the sh-script that runs your application), and does not complicate the programming of the application.
And everything?
And that's it! All the rest is bare computations - data cheating in variables: support for different file formats, databases, network protocols, etc. This is all application, and in no way complicates the environment in which the programs work and does not introduce new entities.
Bonus
For a snack, I will repeat the list of linux entities and show you how they are all replaced in Inferno:
Linux | Inferno |
---|
files / directories | files / directories |
processes | threads |
terminals | - |
signals | channels |
threads | threads |
pipe | - (that workaround does not count) |
messages | channels |
semaphores | channels |
shared memory | channels |
network sockets | files |
unix sockets | files |
pseudo-terminals | - |