Chapter 3 Process Management 3.1 process
- Process is the procedure that is in the execution period.
- A process is a real-time result of the program code being executed.
- The kernel Dispatches objects that are threads and not processes.
In modern operating systems, the process provides two virtual mechanisms:
虚拟处理器 虚拟内存
- A process is a generic term for a program that is in execution and related resources.
- Processes include code snippets and other resources.
Several functions:
fork():创建新进程exec():创建新的地址空间并把新的程序载入其中clone():fork实际由clone实现exit():退出执行wait4():父进程查询子进程是否终结
Wait (), Waitpid (): The program exits execution and becomes zombie, calling both to destroy.
3.2 Process descriptor and task structure
- The kernel stores the list of processes in a two-way circular chain table called the task queue.
- Each item in the list is a structure of type task_struct, called the process descriptor.
- The type of the process descriptor is task_struct, which contains the following data:
3.2.1 Assigning process descriptors
- Linux allocates task_struct structures through the slab allocator, which can achieve object reuse and cache coloring .
- Allocation: The end of the stack for each task (for example, for an upward-growing stack, which is at the top of the stack) has struct threadinfo, which points to the taskstruct body
- The thread info structure for each task isallocated at the end of its kernel stack. a task field in a structure holds a pointer to the actual task struct of the job.
3.2.2 Process Descriptor Storage
- The kernel identifies each process through a unique process identity value PID.
- The PID type is PIDT, which is actually an int type, the maximum value is set to 32768 by default, and if necessary, a system administrator can modify the/proc/sys/kernel/pidmax limit.
- The PID is stored in the respective process descriptor.
- Most of the code in the kernel that processes the processing process is done through task_struct, so you need to find the process descriptor for the currently running process through the current macro
In the X86 system, current blocks the 13 significant bits of the stack pointer, which is used to calculatethe offset of the thread info (current thread_info function)
movl $-8192, %eaxandl %esp,%eax
3.2.3 Process Status
The state field in the process descriptor is used to describe the current status of the process. A total of five states, marked as follows:
- Task_running (Run): The process is executable, is executing, or waits for execution in the run queue
- Task_interruptible (interruptible): process is sleeping/blocked
- Task_uninterruptible (non-interruptible): The sleep/blocked process is not awakened by the signal
- Task_traced: Processes that are tracked by other processes
- Task_stopped (STOP): The process stops executing and the process is not operational or operational. You can enter this state when you receive a signal such as Sigstop, SIGTSTP, Sigttin, Sigttou, or when you receive any signal during commissioning.
The status transition diagram is as follows:
3.2.4 Setting the current process state
3.2.5 Process Context
- Executable code is executed from an executable file loaded into the address space of the process. When a program executes a system call, the kernel "executes on behalf of the process" and is in the context of the process
- Contrast: In an interrupt context, the system does not represent process execution-there is no process to interfere with these interrupt handlers
3.2.6 Process Family Tree
- All processes are descendants of the init process with PID 1
For a given process, get the next process in the list:
- list_entry(task->tasks.prev,struct- task_struct,tasks)
3.3 Process Creation
The mechanism by which the general operating system generates processes:
1. 在新的地址空间创建进程2. 读入可执行文件3. 执行
The UNIX mechanism:
fork()和exec()。 fork(): 通过拷贝当前进程创建一个子进程。
The difference between a child process and a parent process is only pid,ppid and certain resources and metrics
exec(): 读取可执行文件并将其载入地址空间开始运行。
3.3.1 Write-time copy
- Linux fork () uses write-time copies to postpone or even dispense copies. The kernel does not replicate the entire address space when it creates a new process, but rather allows the parent process and child processes to share the same copy, until the child process/parent process needs to write it.
- Thus, the actual cost of fork is simply to copy the page table of the parent process and create a unique process descriptor for the child process
3.3.2 Fork ()
-** Linux implements fork** through the clone system call-the approximate steps to create a process are as follows:
fork()、vfork()、__clone()都根据各自需要的参数标志调用clone()。 由clone()去调用do_fork()。 do_fork()调用copy_process()函数,然后让进程开始运行。 返回do_fork()函数,如果copy_process()函数成功返回,新创建的子进程被唤醒并让其投入运行。
The generic kernel chooses the child process to execute first .
3.3.3 Vfork ()
The vfork () system call and the fork () function are the same except for page table entries that do not copy the parent process. Ideally, do not call Vfork ().
子进程作为父进程的一个单独的线程在它的地址空间里运行 ,父进程被阻塞,直到子进程退出或执行exec()。子进程不能向地址空间写入。
The implementation of the Vfork () system call is done by passing a special flag to clone ().
Call copyprocess () Yes,the Vfor_done member of the task struct is set to null.
- When you perform a Dofork (), if given a specific flag, vfordone points to a specific address.
- After the child process begins execution, the parent process does not resume execution immediately, but waits until the child process sends a signal to it through the vfor donepointer. When mmrelease () is called, the function is used for the process to exit the memory address space and to check if Vfor_done is empty, and if not empty, a signal is sent to the parent process.
- Back to dofork (), the parent process wakes up and returns. # # 3.4 Threads implemented in Linux # # in a Linux system, threads are considered only a process that shares certain resources with other processes. Each thread has its own taskstruct
3.4.1 Creating Threads
Similar to a normal process, except that you need to pass some parameter flags to indicate the shared resource when you call Clone ().
3.4.2 Kernel Thread
The difference from a normal process is that the kernel thread does not have a separate address space.
- 它只能通过其他内核线程创建;内核通过kthread内核进程衍生所有的内核线程 - 新创建的线程处于不可运行状态,直到wake_up_process()明确地唤醒它
# # 3.5 Process End # #-When the process ends, the kernel must release the resources it occupies and inform the parent process.
Reason for process termination: typically from itself, when called by the exit () system call.
显式的调用隐式的从某个程序的主函数返回
Most rely on do_exit () to complete. There are several key points:
……给子进程重新找养父(线程组中的其他线程或者init进程)调用schedule()切换到新的进程……
- After that, the process is not operational and is inexit Zonbie, and all of the memory used is the kernel stack, the threadinfo structure, and the task_struct structure. The only purpose of the process at this time is to provide information to its parent process.
3.5.1 Deleting a process descriptor
Releasing the TASK_STRUCT structure occurs after the parent process obtains the terminated child process information and notifies the kernel that it is not concerned, the required system call is WAIT4 ():
挂起调用它的进程,直到其中的一个子进程退出,此时函数返回该子进程的PID。
- When you release the process descriptor, you need to call Release_task ().
3.5.2 Orphan Process
- Overview: The parent process exits before the process, leaving behind the child process, the orphan process
- The workaround:
Summarize
In this chapter, I know the core concept of the operating system-the process, but also with the book to learn the general nature of the process of importance, and so on, very interesting.
Resources
The third edition of the original book "Linux Kernel Design and implementation"
Design and implementation of Linux kernel chapter III of the book reading and finishing