See: Understanding the Linux Kernel, 3rd Edition by Daniel P. Bovet, Marco Cesati
- Publisher: O'Reilly
- Pub Date: November 2005
- ISBN: 0-596-00565-2
- Pages: 942
In their introduction, Daniel P. Bovet, and Marco Cesati, said:
Technically speaking, Linux is a true Unix kernel, although it is not a full Unix operating system, because it does not include all the
applications such as filesystem utilities, windowing systems and
graphical desktops, system administrator commands, text editors,
compilers, and so on. What you read in this book and see in the Linux
kernel, therefore, may help you understand the other Unix variants
In the next paragraphs, I will try to address your points of view based on my understanding to the facts presented in "Understanding the Linux Kernel" which is to a very large extent are similar to those in Unix.
What a process means?:
Processes are like human beings, they are generated, they have a more or less significant life, they optionally generate one or more child processes, and eventually they die. A process has five fundamental parts: code ("text"), data (VM), stack, file I/O, and signal tables
The purpose of a process in the Kernel is to act as an entity to which system resources (CPU time, memory, etc.) are allocated. When a process is created, it is almost identical to its parent. It receives a (logical) copy of the parent's address space and executes the same code as the parent, beginning at the next instruction following the process creation system call. Although the parent and child may share the pages containing the program code (text), they have separate copies of the data (stack and heap), so that changes by the child to a memory location are invisible to the parent (and vice versa).
How Processes Work?
An executing program needs more than just the binary code that tells the computer what to do. The program needs memory and various operating system resources in order to run. A “process” is what we call a program that has been loaded into memory along with all the resources it needs to operate. A thread is the unit of execution within a process. A process can have anywhere from just one thread to many threads. When a process starts, it is assigned memory and resources. Each thread in the process shares that memory and resources. In single-threaded processes, the process contains one thread. The process and the thread are one and the same, and there is only one thing happening. In multithreaded processes, the process contains more than one thread, and the process is accomplishing a number of things at the same time.
The mechanics of a multi-processing system, include lightweight and heavyweight processes:
In a heavyweight process, multiple processes are running together in parallel. Each heavyweight process in parallel has its own memory address space. Inter-process communication is slow as processes have different memory addresses. Context switching between processes is more expensive. Processes don’t share memory with other processes. The communication between these processes would involve additional communications mechanisms such as sockets or pipes.
In a lightweight process, also called threads. Threads are used to share and divide the workload. Threads use the memory of the process they belong to. Inter-thread communication can be faster than inter-process communication because threads of the same process share memory with the process they belong to. as a result the communication between the threads is very simple and efficient. Context switching between threads of the same process is less expensive. Threads share memory with other threads of the same process
There are two types of threads: user-level threads and kernel-level threads. User-level threads avoid the kernel and manage the work on its own. User-level threads have a problem that a single thread can monopolize the time slice thus starving the other threads within the task. User-level threads are usually supported above the kernel in user space and are managed without kernel support. The kernel knows nothing about user-level threads and manage them as if they were single-threaded processes. As such, user-level threads are very fast, it operates 100X faster than kernel threads.
Kernel-level threads often are implemented in the kernel using several tasks. In this case, the kernel schedules each thread within the timeslice of each process. Here, since the clock tick will determine the switching times, a task is less likely to hog the timeslice from the other threads within the task.Kernel level threads are supported and managed directly by the operating system.
The relationship between user-level threads and Kernel-level threads is not completely independent, in fact there is an interaction between these two levels.
In general, user-level threads can be implemented using one of four models:
many-to-one, one-to-one, many-to-many and two-level models. All these models maps user-level threads to kernel-level threads, and cause an interaction in different degrees between both levels.
Threads vs. Processes
- The program starts out as a text file of programming code,
- The program is compiled or interpreted into binary form,
- The program is loaded into memory,
- The program becomes one or more running processes.
- Processes are typically independent of each other,
- While threads exist as the subset of a process.
- Threads can communicate with each other more easily than processes can,
- But threads are more vulnerable to problems caused by other threads in the same process
Understanding the Linux Kernel, 3rd Edition
More 1 2 3 4 5
Now, let's simplify all these terms (this paragraph is from my perspectives).
Kernel is an interface between software and hardware. In other words, the kernel acts like a brain. It manipulates a relationship between the genetic material (i.e. codes and its derivatives software), and body systems (i.e. hardware or muscles).
This brain (i.e. kernel) sends signals to processes which act accordingly. Some of these processes are like muscles (i.e. threads), each muscle has its own function and task but they all work together to finish the workload. The communication between these threads (i.e. muscles) is very efficient and simple, so they achieve their job smoothly, quickly and effectively. Some of the threads (i.e. muscles) are under user's control (like the muscles in our hands and legs). Others are under the brain control (like the muscles in our stomach, eye, heart which we don't control).
User-space threads avoids the kernel and manages the tasks itself. Often this is called "cooperative multitasking", and indeed it is like our upper and lower extremities, it is under our own control and it works all together to achieve work (i.e. exercises or ...) and doesn't need direct orders from the brain. On the other side, Kernel-Space threads are completely controlled by the kernel and its scheduler.
In a response to your questions:
Is a process always implemented based on one or more light weight processes? Figure 3.4 seems to say yes. Why does Figure 3.5(a) show processes directly on top of CPUs?
Yes, there are lightweight processes called threads, and heavyweight processes.
A heavyweight process (you can call it signal thread process) requires the processor itself to do more work to order its execution, that's why Figure 3.5(a) shows processes directly on top of CPUs.
Is a light weight process always implemented based on a kernel thread? Figure 3.4 seems to say yes. Why does Figure 3.5(b) show light weight processes directly on top of processes?
No, light weight processes are divided into two categories: User-level and kernel-level processes, as mentioned above. User-level process relies on its own library to process its tasks. The kernel itself schedule kernel-level process. User level threads can be implemented using one of four modeled:
many-to-one, one-to-one, many-to-many and two-level. All, these models maps user-level threads to kernel-level threads.
Are kernel threads the only entities able to be scheduled?
No, Kernel-level threads, are created by the kernel itself. They are different than user-level threads in the fact that the kernel-level threads do not have a limited address space. They live solely in kernel-space, never switching to the realm of user-land. However, they are fully schedulable and preemptible entities, just like normal processes (note: it is possible to disable almost all interrupts for important kernel actions). The purpose of kernel’s own threads is mainly to perform maintenance duties on the system. Only kernel can start or stop a kernel thread. On the other side, user-level process can schedule itself based on it is own library and at the same time it can be scheduled by the kernel based on the two-level and many-to-many models (mentioned above), which allow for certain user-level threads to be bound to a single kernel-level thread.
Are light weight processes scheduled only indirectly via scheduling the underlying kernel threads?
The kernel threads are controlled by the kernel scheduler itself. Supporting threads at user level means that there is a user level library that is linked with the application and this library (not the CPU) provides all of the management in the runtime support for threads. It will support data structures that are needed to implement the thread abstraction and provide all the scheduling synchronization and other mechanisms that are needed to make resources management decision for these threads. Now, some of the user level thread processes can be mapped into the underlying kernel level threads and this includes one-to-one, one-to-many and many-to-many mapping.
Are processes scheduled only indirectly via scheduling the underlying lightweight processes?
It depends on whether it is a heavyweight or lightweight process. Heavy are processes scheduled by the kernel itself. light process can be managed at the kernel level and at the user level.