A: As the name suggests, such processes are defunct
but are somehow still alive. In reality, they are dead because their resources
(RAM, connections to
peripherals, etc.) have already been released so that they cannot and never
will run again.
The reason lies in the process creation and destruction
structure under Unix.
A program terminates when two events occur — first, the program must be killed
by another process
or by a user (this is usually done by sending a SIGTERM
or SIGKILL signal,
which is equivalent to
terminating the process regularly); second, the parent process from which the
process originates must invoke
or have already invoked the wait4 (read:
wait for) system call when the
child process terminates.
This
confirms to the kernel that the parent process has acknowledged the death of
the child. The system
call
enables the kernel to free resources reserved by the child process.
A
zombie occurs when only the first condition (the program is terminated) applies
but not the second
(wait4).
A process always switches briefly to the zombie state between termination and
removal of its data
from the process table. In some cases (if, e.g., the parent process is badly
programmed and does not
issue a wait call), a
zombie can firmly lodge itself in the process table and remain there until the
next reboot.
This can be seen by reading the output of process tools such as ps
or top. This is
hardly a problem as the residual data take up little space in the kernel.
If
the system is in kernel mode and is processing a system call, no other process
in the system is
able to cause withdrawal of CPU time. The scheduler is forced to wait until
execution of the system
call has terminated before it can select another process. However, the system
call can be suspended
by an interrupt.
Interrupts can suspend processes in user mode and in kernel
mode. They have the highest priority
because it is essential to handle them as soon as possible after they are
issued.
A particularity that does not occur in normal userspace programming is per-CPU variables. They are declared with DEFINE_PER_CPU(name, type), where name is the variable name and type is the data type (e.g., int[3], struct hash, etc.). On single-processor systems, this is not different from regular variable declaration. On SMP systems with several CPUs, an instance of the variable is created for each CPU.
The instance for a particular CPU is selected with get_cpu(name, cpu), where smp_processor_id(), which returns the identifier of the active processor, is usually used as the argument for cpu.
Q: How Interrupts handled between CPUs?
Interrupts are generally shared evenly between CPUs.
Whenever
a CPU receives an interrupt notification, it invokes the handler associated
with that interrupt, which is identified by a number. During the handler's
execution in which the kernel code is said to be in interrupt
context interrupts are disabled for the CPU
serving the interrupt. This means that if a CPU is busy serving one interrupt,
it cannot receive other interrupts, whether of the same type or of different
types.
Nor can the CPU execute
any other process: it belongs totally to the interrupt handler and cannot be
preempted.
In short, interrupt handlers are nonpreemptible and
non-reentrant
Therefore, the work done by interrupt handlers should be as quick as possible.
The amount of processing needed by the interrupt handlers during interrupt
context depends on the type of event. A keyboard, for instance, may simply send
an interrupt every time a key is pressed, which requires very little effort to
be handled: the handler simply needs to store the code of the key somewhere,
and run a few times per second at most.
Q: Bottom Half Hanlder in Interrupt?
Even if the action triggered by an interrupt needs a lot of CPU
time, most of this action can usually wait. Interrupts are allowed to preempt
the CPU in the first place because if the operating system makes the hardware
wait too long, it may lose data.
One can define a bottom half as an asynchronous request to execute a
particular function. Normally, when you want to execute a function, you do not
have to request anything you simply invoke it.
No comments:
Post a Comment