⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unix time_share_system .htm

📁 讲解关于UXIX操作系统的资料,包含如何基本操作以及编程.
💻 HTM
📖 第 1 页 / 共 5 页
字号:
file. Still larger files use the twelfth device address of the i-node to point 
to a double-indirect block naming 128 indirect blocks, each pointing to 128 
blocks of the file. If required, the thirteenth device address is a 
triple-indirect block. Thus files may conceptually grow to 
[(10+128+128^2+128^3)*512] bytes. Once opened, bytes numbered below 5120 can be 
read with a single disk access; bytes in the range 5120 to 70,656 require two 
accesses; bytes in the range 70,656 to 8,459,264 require three accesses; bytes 
from there to the largest file (1,082,201,088) require four accesses. In 
practice, a device cache mechanism (see below) proves effective in eliminating 
most of the indirect fetches. </P>
<P>The foregoing discussion applies to ordinary files. When an I/O request is 
made to a file whose i-node indicates that it is special, the last 12 device 
address words are immaterial, and the first specifies an internal <B>device 
name</B>, which is interpreted as a pair of numbers representing, respectively, 
a device type and subdevice number. The device type indicates which system 
routine will deal with I/O on that device; the subdevice number selects, for 
example, a disk drive attached to a particular controller or one of several 
similar terminal interfaces. </P>
<P>In this environment, the implementation of the <I>mount</I> system call 
(Section 3.4) is quite straightforward. <I>mount</I> maintains a system table 
whose argument is the i-number and device name of the ordinary file specified 
during the <I>mount</I>, and whose corresponding value is the device name of the 
indicated special file. This table is searched for each i-number/device pair 
that turns up while a path name is being scanned during an <I>open</I> or 
<I>create</I>; if a match is found, the i-number is replaced by the i-number of 
the root directory and the device name is replaced by the table value. </P>
<P>To the user, both reading and writing of files appear to be synchronous and 
unbuffered. That is, immediately after return from a <I>read</I> call the data 
are available; conversely, after a <I>write</I> the user's workspace may be 
reused. In fact, the system maintains a rather complicated buffering mechanism 
that reduces greatly the number of I/O operations required to access a file. 
Suppose a <I>write</I> call is made specifying transmission of a single byte. 
The system will search its buffers to see whether the affected disk block 
currently resides in main memory; if not, it will be read in from the device. 
Then the affected byte is replaced in the buffer and an entry is made in a list 
of blocks to be written. The return from the <I>write</I> call may then take 
place, although the actual I/O may not be completed until a later time. 
Conversely, if a single byte is read, the system determines whether the 
secondary storage block in which the byte is located is already in one of the 
system's buffers; if so, the byte can be returned immediately. If not, the block 
is read into a buffer and the byte picked out. </P>
<P>The system recognizes when a program has made accesses to sequential blocks 
of a file, and asynchronously pre-reads the next block. This significantly 
reduces the running time of most programs while adding little to system 
overhead. </P>
<P>A program that reads or writes files in units of 512 bytes has an advantage 
over a program that reads or writes a single byte at a time, but the gain is not 
immense; it comes mainly from the avoidance of system overhead. If a program is 
used rarely or does no great volume of I/O, it may quite reasonably read and 
write in units as small as it wishes. </P>
<P>The notion of the i-list is an unusual feature of Unix. In practice, this 
method of organizing the file system has proved quite reliable and easy to deal 
with. To the system itself, one of its strengths is the fact that each file has 
a short, unambiguous name related in a simple way to the protection, addressing, 
and other information needed to access the file. It also permits a quite simple 
and rapid algorithm for checking the consistency of a file system, for example, 
verification that the portions of each device containing useful information and 
those free to be allocated are disjoint and together exhaust the space on the 
device. This algorithm is independent of the directory hierarchy, because it 
need only scan the linearly organized i-list. At the same time the notion of the 
i-list induces certain peculiarities not found in other file system 
organizations. For example, there is the question of who is to be charged for 
the space a file occupies, because all directory entries for a file have equal 
status. Charging the owner of a file is unfair in general, for one user may 
create a file, another may link to it, and the first user may delete the file. 
The first user is still the owner of the file, but it should be charged to the 
second user. The simplest reasonably fair algorithm seems to be to spread the 
charges equally among users who have links to a file. Many installations avoid 
the issue by not charging any fees at all. </P>
<H4>V. PROCESSES AND IMAGES </H4>
<P>An <B>image</B> is a computer execution environment. It includes a memory 
image, general register values, status of open files, current directory and the 
like. An image is the current state of a pseudo-computer. </P>
<P>A <B>process</B> is the execution of an image. While the processor is 
executing on behalf of a process, the image must reside in main memory; during 
the execution of other processes it remains in main memory unless the appearance 
of an active, higher-priority process forces it to be swapped out to the disk. 
</P>
<P>The user-memory part of an image is divided into three logical segments. The 
program text segment begins at location 0 in the virtual address space. During 
execution, this segment is write-protected and a single copy of it is shared 
among all processes executing the same program. At the first hardware protection 
byte boundary above the program text segment in the virtual address space begins 
a non-shared, writable data segment, the size of which may be extended by a 
system call. Starting at the highest address in the virtual address space is a 
stack segment, which automatically grows downward as the stack pointer 
fluctuates. </P>
<H4>5.1 Processes </H4>
<P>Except while the system is bootstrapping itself into operation, a new process 
can come into existence only by use of the <I>fork</I> system call: 
<DL>
  <DT>
  <DD><TT><PRE>processid = fork()
</PRE></TT></DD></DL>When <I>fork</I> is executed, the process splits into two 
independently executing processes. The two processes have independent copies of 
the original memory image, and share all open files. The new processes differ 
only in that one is considered the parent process: in the parent, the returned 
<I>processid</I> actually identifies the child process and is never 0, while in 
the child, the returned value is always 0. 
<P></P>
<P>Because the values returned by <I>fork</I> in the parent and child process 
are distinguishable, each process may determine whether it is the parent or 
child. </P>
<H4>5.2 Pipes </H4>
<P>Processes may communicate with related processes using the same system 
<I>read</I> and <I>write</I> calls that are used for file-system I/O. The call: 
<DL>
  <DT>
  <DD><TT><PRE>filep = pipe()
</PRE></TT></DD></DL>returns a file descriptor <I>filep</I> and creates an 
inter-process channel called a <B>pipe</B>. This channel, like other open files, 
is passed from parent to child process in the image by the <I>fork</I> call. A 
<I>read</I> using a pipe file descriptor waits until another process writes 
using the file descriptor for the same pipe. At this point, data are passed 
between the images of the two processes. Neither process need know that a pipe, 
rather than an ordinary file, is involved. 
<P></P>
<P>Although inter-process communication via pipes is a quite valuable tool (see 
Section 6.2), it is not a completely general mechanism, because the pipe must be 
set up by a common ancestor of the processes involved. </P>
<H4>5.3 Execution of programs </H4>
<P>Another major system primitive is invoked by 
<DL>
  <DT>
  <DD><TT><PRE>execute(file, arg1, arg2, ... , argn)
</PRE></TT></DD></DL>which requests the system to read in and execute the 
program named by <I>file</I>, passing it string arguments <I>arg1</I>, 
<I>arg2</I>, <I>...</I>, <I>argn</I>. All the code and data in the process 
invoking <I>execute</I> is replaced from the <I>file</I>, but open files, 
current directory, and inter-process relationships are unaltered. Only if the 
call fails, for example because <I>file</I> could not be found or because its 
execute-permission bit was not set, does a return take place from the 
<I>execute</I> primitive; it resembles a ``jump'' machine instruction rather 
than a subroutine call. 
<P></P>
<H4>5.4 Process synchronization </H4>
<P>Another process control system call: 
<DL>
  <DT>
  <DD><TT><PRE>processid = wait(status)
</PRE></TT></DD></DL>causes its caller to suspend execution until one of its 
children has completed execution. Then <I>wait</I> returns the <I>processid</I> 
of the terminated process. An error return is taken if the calling process has 
no descendants. Certain status from the child process is also available. 
<P></P>
<H4>5.5 Termination </H4>
<P>Lastly: 
<DL>
  <DT>
  <DD><TT><PRE>exit(status)
</PRE></TT></DD></DL>terminates a process, destroys its image, closes its open 
files, and generally obliterates it. The parent is notified through the 
<I>wait</I> primitive, and <I>status</I> is made available to it. Processes may 
also terminate as a result of various illegal actions or user-generated signals 
(Section VII below). 
<P></P>
<H4>VI. THE SHELL </H4>
<P>For most users, communication with the system is carried on with the aid of a 
program called the shell. The shell is a command-line interpreter: it reads 
lines typed by the user and interprets them as requests to execute other 
programs. (The shell is described fully elsewhere [9], so this section will 
discuss only the theory of its operation.) In simplest form, a command line 
consists of the command name followed by arguments to the command, all separated 
by spaces: 
<DL>
  <DT>
  <DD><TT><PRE>command arg1 arg2 ... argn
</PRE></TT></DD></DL>The shell splits up the command name and the arguments into 
separate strings. Then a file with name <I>command</I> is sought; <I>command</I> 
may be a path name including the ``/'' character to specify any file in the 
system. If <I>command</I> is found, it is brought into memory and executed. The 
arguments collected by the shell are accessible to the command. When the command 
is finished, the shell resumes its own execution, and indicates its readiness to 
accept another command by typing a prompt character. 
<P></P>
<P>If file <I>command</I> cannot be found, the shell generally prefixes a string 
such as <I>/bin/</I> to <I>command</I> and attempts again to find the file. 
Directory <I>/bin</I> contains commands intended to be generally used. (The 
sequence of directories to be searched may be changed by user request.) </P>
<H4>6.1 Standard I/O </H4>
<P>The discussion of I/O in Section III above seems to imply that every file 
used by a program must be opened or created by the program in order to get a 
file descriptor for the file. Programs executed by the shell, however, start off 
with three open files with file descriptors 0, 1, and 2. As such a program 
begins execution, file 1 is open for writing, and is best understood as the 
standard output file. Except under circumstances indicated below, this file is 
the user's terminal. Thus programs that wish to write informative information 
ordinarily use file descriptor 1. Conversely, file 0 starts off open for 
reading, and programs that wish to read messages typed by the user read this 
file. </P>
<P>The shell is able to change the standard assignments of these file 
descriptors from the user's terminal printer and keyboard. If one of the 
arguments to a command is prefixed by ``&gt;'', file descriptor 1 will, for the 
duration of the command, refer to the file named after the ``&gt;''. For 
example: 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -