Transcript Document

UNIX PROCESSES
What is a Unix Process
• An entity that executes a given piece of
code
– has its own execution stack
– its own set of memory pages
– its own file descriptors table
– a unique process ID
Re-entrancy
• The ability to have the same function (or part of
a code) being in some phase of execution, more
than once at the same time.
• two or more processes try to execute this piece
of code at the same time
• with a multi-process code, we don't have
conflicts of variables, because normally the data
section of each process is separate from that of
other processes (so process A that runs program
P and process B that runs the same program P,
have distinct copies of the global variable 'i' of
that program)
Process Creation
• The fork() system call is the basic way to
create a new process.
• It is also a very unique system call, since it
returns twice(!) to the caller.
fork()
• This system call causes the current
process to be split into two processes - a
parent process, and a child process.
• All of the memory pages used by the
original process get duplicated during the
fork() call, so both parent and child
process see the exact same image.
fork() (contd.)
• The only distinction is when the call returns.
– When it returns in the parent process, its return value
is the process ID (PID) of the child process.
– When it returns inside the child process, its return
value is '0'.
– If for some reason this call failed (not enough
memory, too many processes, etc.), no new process
is created, and the return value of the call is '-1'.
• In case the process was created successfully,
both child process and parent process continue
from the same place in the code where the fork()
call was used.
fork() Example
• Adress of the example
Note
• fork() copies also a memory area known as the
'U Area' (or User Area). This area contains,
amongst other things, the file descriptor table of
the process. This means that after returning from
the fork() call, the child process inherits all files
that were open in the parent process. If one of
them reads from such an open file, the
read/write pointer is advanced for both of them.
On the other hand, files opened after the call to
fork() are not shared by both processes. Further
more, if one process closes a shared file, it is
still kept open in the other process.
Child Process Termination
• there are two possibilities
– the parent process exits before the child
– the child exits before the parent
Child exits before parent
• When a child process exits, it is not
immediately cleared off the process table.
Instead, a signal is sent to its parent
process, which needs to acknowledge it's
child's death, and only then the child
process is completely removed from the
system. In the duration before the parent's
acknowledgment and after the child's exit,
the child process is in a state called
"zombie".
The wait() System Call
• The simple way of a process to acknowledge the
death of a child process is by using the wait()
system call.
• When wait() is called, the process is suspended
until one of its child processes exits, and then
the call returns with the exit status of the child
process.
• If it has a zombie child process, the call returns
immediately, with the exit status of that process.
Parent exits before child
• When a process exits (terminates), if it had any
child processes, they become orphans. An
orphan process is automatically inherited by the
'init' process (process number 1 on normal Unix
systems), and becomes a child of this 'init'
process. This is done to ensure that when the
process terminates, it does not turn into a
zombie, because 'init' is written to properly
acknowledge the death of its child processes.
Asynchronous Child Death
Notification
• When a child process dies, a signal,
SIGCHLD (or SIGCLD) is sent to its parent
process.
• using a proper signal handler, the parent
will get an asynchronous notification, and
then when it'll call wait(), the system
assures that the call will return
immediately, since there is already a
zombie child.
• pid t waitpid (pid t pid, int *status, int
options);
Asynchronous Child Death
Notification Example
• Adress of the example
execve
• system call allows a process to run a new
program
• #include <unistd h>
int execve (const char *pathname, const
char *argv [], const char *envp[]);
• triggers the execution of a new program
execve (contd.)
• pathname specifies the name of the file to
be executed
• The parameter argv should point to a string
of characters representing an argument
• The parameter envp specifies the variables
in the program environment
• Each of the elements should contain the
address of a character string of the form
“name_of_variable=value”