10 days the second day of learning the Linux kernel---process

Source: Internet
Author: User
Tags signal handler

All say this theme is good, even I feel a little too big, but I think I still have to persist, efforts in a limited time to learn the secret of the Linux kernel, but also hope that we have more guidance, let me more progress. Today is all about the process, this is in the sophomore time confused me, the result then I stopped, the main point here is why the introduction of the process, the process in the Linux space is implemented, and describes all the process execution related data structure, and finally the exception and interrupt and other asynchronous execution process, How they interact with the Linux kernel, let me give you a detailed look at the intricacies of this process.

First we need to make clear a concept, we say the program refers to a set of functions of the executable file, and the process is a specific program of the individual instances, the process is the hardware provides resources to operate the basic unit. Before we proceed, we need to understand a few naming conventions, often called "Tasks" and "processes".

In fact, the process has a life cycle, the process from the creation will go through various states after death, the following example to help you understand how the process is instantiated.

 1#include <stdio.h>2#include <sys/types.h>3#include <sys/stat.h>4 #include <fcnt1.h> 5 6 int main (int argc, Char span class= "variable" >*argv[]) 7 {8 int fd; 9 int pid;10 pid = fork (); if (PID = = 0) ("execle 
                 
                  /bin/ls ", NULL), 
                  exit (2),}17 if (waitpid (PID) <0) printf ("wait error\n"), PID = fork (); if (PID = = 0) = open ("chapter_2.txt", o_rdonly); close (FD); }27 if (waitpid (PID) <0) printf ("wait Error\n "), exit (0);          
                 
Creat_process

A process consists of a number of properties that make the process different from each other, in the kernel, the process descriptor is a TASK_STRUCT structure that holds the properties and related information for the process, and the kernel uses the circular doubly linked list task_list to hold all the process descriptors. The task_struct of the currently running process is saved with the global variable current. As for the definition of task_struct, you can see include/linux/sched.h here I can't speak spicy, but I have to explain the difference between process and thread, the process consists of one or more threads, each thread corresponds to a task_struct, It contains a unique thread ID. Threads act as the basic unit of dispatch and allocation, while processes act as the basic unit of resources; not only can the processes be executed concurrently, but also concurrently between multiple threads of the same process; a process is an independent unit of resources that does not have system resources but can access resources that belong to the process.

Process Descriptor (task_struct) Some fields mean, there are too many process-related fields, I list some of the following, assuming that the process is P.

    • State:p process State, change it with Set_task_state and set_current_state macros, or assign values directly.
    • Thread_info: A pointer to the THREAD_INFO structure.
    • Run_list: Assuming p status is task_running, the priority is k,run_list to connect p to the list of running processes with a priority of K.
    • Tasks: Connect p to the process chain list.
    • Ptrace_children: The linked list header, all elements in the list are child processes of p that are tracked by the debugger program.
    • When Ptrace_list:p is debugged, all elements in the list are child processes of p that are tracked by the debugger program.
    • Pid:p process Identity (PID).
    • PID of the lead process for the thread group where the Tgid:p is located.
    • REAL_PARENT:P the process descriptor pointer of the real parent process.
    • The process descriptor pointer of the PARENT:P parent process, which is the descriptor pointer of the debugger process when it is debugged.
    • Children:p the child process chain list.
    • Sibling: Link p to the sibling process List of p.
    • A descriptor pointer to the lead process for the thread group where the Group_leader:p is located.

We understand that any process is created by another process, and the operating system completes the process creation through the fork (), Vfork (), Clone () system call. Process-created system calls such as:

These three systems eventually call the Do_fork () function, Do_fork () is the kernel function, which completes most of the work related to process creation, let me briefly introduce the fork (), the Vfork (), the Clone () function.

Fork () function

The fork () function returns two times, a child process at a time, a return value of 0, and a parent process that returns the PID of the child process.

Vfork () function

is similar to the fork () function, but the parent process of the former is blocked until the child process calls exit () or EXEC ().

Clone () function

The Clone () function accepts a pointer to a function and the function's arguments, which are called by Do_fork () when the child process is created.

The only difference between the three is that those flags that are set in the final call to the Do_fork () function are not the same as the following table.

Fork () Vfork () Clone
SIGCHLD X X
Clone_vfork X
Clone_vm X

The Do_fork () function uses the auxiliary function copy_process () to create the process descriptor and all other kernel data structures required by the child process execution, and in the Linux kernel, the response function of the system call Fork () function for the user to create the process is sys_fork (), Sys_clone (), Sys_vfork (). These three functions are implemented by calling the kernel function do_fork (). The following is an analysis of the specific Do_fork () function program code, which is located in the Kernel/fork.c file.

  1 int Do_fork (unsigned long clone_flags,unsigned long stack_start, struct Pt_regs *regs,2unsigned long stack_size)3 {4 int retval;5 struct task_struct *p;6 struct completion vfork;78 retval =-eperm;9if (Clone_flags & Clone_pid)11 {if (current->pid)Goto Fork_out;14}15Reval =-enomem;17p = alloc_task_struct (); //allocating memory to establish a TASK_STRUCT structure for a new processif (!p)Goto Fork_out;21st*p = *current; //Copy the contents of the TASK_STRUCT structure of the current process to the PCB structure of the new process23retval =-eagain;2526//The following code assigns values to data members of different values in the parent, child process task_struct structure27if (Atomic_read (&p->user->processes) >= p->rlim[rlimit_nproc].rlim_cur&&!capable (cap_sys_admin) &&!capable (Cap_sys_resource))-Goto Bad_fork_free;31Atomic_inc (&p->user->__count); //Count Counter plus 1Atomic_inc (&p->user->processes); //Number of processes plus 134if (nr_threads >= max_threads)Bad_fork_cleanup_count Goto;37Get_exec_domain (P->exec_domain);39if (p->binfmt && p->binfmt->module)__mod_inc_use_count (P->binfmt->module); //Executable file BINFMT Structure share count + 1p->did_exec = 0; //Process not executedp->swappable = 0; //Process cannot be swapped outP->state = task_uninterruptible; //Status of the Reset processCopy_flags (CLONE_FLAGS,P); //Copy process flag bitP->pid = Get_pid (clone_flags); //Assign a process flag number to a new processP->run_list.next = NULL;P->run_list.prev = NULL;P->run_list.cptr = NULL;50Wuyi Init_waitqueue_head (&p->wait_childexit); //Initializing the Wait_childexit queue52P->vfork_done = NULL;54if (Clone_flags & clone_vfork) {P->vfork_done = &vfork;Init_completion (&vfork);58}59Spin_lock_init (&p->alloc_lock);61p->sigpending = 0;63Init_sigpending (&p->pending);P->it_real_value = P->it_virt_value = P->it_prof_value = 0; //Initializing Time data membersP-&GT;IT_REAL_INCR = P-&GT;IT_VIRT_INCR = P-&GT;IT_PROF_INCR = 0; //Initializing the timer structureInit_timer (&p->real_timer);P->real_timer.data = (unsigned long) p;P->leader = 0;P-&GT;TTY_OLD_PGRP = 0;P->times.tms_utime = P->times.tms_stime = 0; //Various run times of the initialization processP->times.tms_cutime = P->times.tms_cstime = 0;73#ifdef CONFIG_SMP//Initialize symmetric processor members74 {int i;P->cpus_runnable = ~0UL;P->processor = Current->processor;(i = 0; i < Smp_num_cpus; i++)p->per_cpu_utime[i] = p->per_cpu_stime[I] = 0;Spin_lock_init (&p->sigmask_lock);81}82#endifP->lock_depth =-1; //Note: Here-1 represents no, indicating that the kernel is not locked when context switchesP->start_time = jiffies; //Set the start time of a process86Init_list_head (&p->local_pages);retval =-enomem;89if (Copy_files (Clone_flags, p))//Copy the files pointer of the parent process, sharing the file that the parent process has openedBad_fork_cleanup Goto;92if (Copy_fs (Clone_flags, p))//Copies the FS pointer of the parent process, sharing the parent process file system94 Goto Bad_fork_cleanup_files;95if (Copy_sighand (Clone_flags, p))//The child process shares the signal handler pointer of the parent processBAD_FORK_CLEANUP_FS Goto;98if (copy_mm (Clone_flags, p)): bad_fork_cleanup_mm; //Copy the MM information of the parent process, share storage Management Information 101 102 retval = copy_thread (0, Clone_flags, Stack_start, Stack_size, P regs); 103//Initialize TSS, LDT, and GDT 104 if (retval) 106 goto BAD_FORK_CLEANUP_MM; 107 108 P->semundo = NULL; //Initialize semaphore member 109 p->prent_exec_id = p-self_exec_id; 111 p->swappable = 1; //Process occupied memory page can be swapped out 113 p->exit_signal = Clone_flag & csignal; p->pdeatch_signal = 0; //Note: Here is the signal sent after the parent process dies 117 118 P->counter = (current->counter + 1) >> 1;//Process dynamic priority, which is set to half of the parent process, it should be noted that this is done with bit manipulation. 119 Current->counter >> =1;121 122 if (!current->counter) 123 current->need_resched = 1; //The reset tag, which actually starts from this place, is split into a parent-child two process. 124 retval = p->pid; 126 127 p->tpid = retval; Init_list_head (&p->thread_group); 129 IRQ (&tasklist_lock); 131 p->p_opptr = current->p_opptr; 133 p->p_pptr = Current->p_pptr; 134 135 if ( ! (Clone_flags & (Clone_parent | Clone_thread)) {136 p->opptr = current; 137 if (! ( P->ptrace & pt_ptraced)) 138 p->p_pptr = current; 139}140 141 if (Clone_flags & Clone_thread) {142 p->t PID = current->tpid; 143 List_add (&p->thread_group,&current->thread_group); 144}145 146 SET_LINKS (p) ; 147 148 hash_pid (p); 149 nr_threads++;150 151 WRITE_UNLOCK_IRQ (&tasklist_lock); if (P->ptrace & PT_PTRACE D) 153 Send_sig (SIGSTOP, p, 1); 154 wake_up_process (P); //Add the new process to the run queue and start the scheduler reschedule, so that the new process gets run chance 155 ++total_forks; 156 if (Clone_flags & CLONE_VFRK) 157 wait_for_completion ( &vfork); 158 159// The following is an error handling section fork_out:161 return retval;162 bad_fork_cleanup_mm:163 exit_mm (p); 164 Bad_fork_ cleanup_sighand:165 Exit_sighand (P); 166 bad_fork_cleanup_fs:167 Exit_fs (p); 168 bad_fork_cleanup_files:169 Exit_ Files (p); 171 bad_fork_cleanup:172 Put_exec_domain (P->exec_domain); 173 174 if (p->binfmt && p->bin Fmt->module) 175 __mod_dec_use_count (P->binfmt->module); 176 bad_fork_cleanup_count:177 Atomic_dec (&p- >user->processes); 178 free_uid (P->user); 179 bad_fork_free:180 free_task_struct (p); 181 goto fork_out;182}
                                                                                                                                         
Fork

A process in Linux has 7 states, and the state field of the task_struct structure of the process indicates the status of the process. The image describes the transformation between the various states, here do not elaborate, we look at the picture experience.

Operational status (task_running)

interruptible Wait (task_interruptible)

Non-disruptive Wait (task_uninterruptible)

Paused State (task_stopped)

Trace status (task_traced): The process is paused or monitored by the debugger.

Zombie State (Exit_zombie): The process was terminated, but the parent process did not invoke the wait class system call.

Zombie Undo State (Task_dead): The parent process initiates a wait class system call, and the process is deleted by the system.

As for the termination of the process, the exit () function has been mentioned above, and there are three ways to terminate the process: explicit and voluntary termination, implicit but voluntary termination, which can be accomplished by the sys_exit () function, Do_exit () function, which is not much to say, understood , to this, we should be the process in the life cycle of the various States, the completion of the majority of the function of the state transformation and so on have been understood, there is need to supplement or do not understand to borrow I some information should be able to process the relevant knowledge has a good grasp, I hope you can understand, then my task is finished half.

Understanding the process-centric state and transformation but to really complete the process of running and terminating, then the basic framework of the kernel must be mastered, now we introduce the basic knowledge of the scheduler, the Scheduler object is a structure called the run queue, describes the queue of priority array, its definition and correlation analysis are as follows:

struct Prio_array {    int nr_active; //Counter, record number    of processes in the priority array  unsigned long bitmap[bitmap_size]; //bitmap is the priority in the record array, the actual length depends on the size    of the system unsigned long integer type  Queue[max_prio]; //queue An array of stored process lists, with each linked list containing a specific priority process};    

Finally, the asynchronous execution process, as we have said, is that the process can break one state to another through the terminal, and the only way to get such a transition is to include exceptions and interrupts asynchronously. (Here spit groove, in fact, this time I am tired, feel good difficult to write, all blame sophomore when the foundation is not good, now a year passed, Junior dog winter vacation sunny day not go out, stay in the laboratory, but this time to meet the theme, head Melon interrupted a bit)

Abnormal:
    • Processor-generated (Fault,trap,abort) exception
    • Programmed exceptions (soft interrupt): triggered by an int or INT3 instruction by a programmer, usually as a trap, useful: implement system calls.

Exceptions, also known as synchronous interrupts, are events that occur inside the entire processor hardware. Exceptions usually occur after the instruction is executed. Most modern processors allow programmers to produce an exception by executing certain instructions. One example is System invocation.

System calls:

Many of the C library routines called by the user-state program are bundling the code with one or more system calls to form a separate function. When a user process invokes one of the functions, a value is placed in the appropriate processor register and a soft interrupt irp (exception) is generated. The soft interrupt then calls the kernel entry point. System calls can pass data between the user space and the kernel space, which is accomplished by two kernel functions: Copy_to_user () and Copy_from_user (). The system call number and all parameters are first stored in the processor register, which indexes the system call table when the x86 exception handler handles soft interrupt 0x80.

Interrupt:
    • Shielded interrupts: All interrupts that have an I/O device request are that the blocked interrupts are always ignored by the CPU until the shield bit is reset.
    • Non-shielded interrupts: very dangerous events (e.g. hardware failure)

Interrupts are performed asynchronously on the processor, meaning that interrupts can occur between early instructions. In general, an interrupt controller is required (x86 8259 interrupt processor). When the interrupt processor has a pending interrupt, it triggers the corresponding int line connected to the processor, and the processor confirms the signal via the trigger line, confirming that the line is connected to the INTA line. At this point, the interrupt processor can transmit the IRQ data to the processor, which is an interrupt acknowledgement period. Specific examples are not good to enumerate, need too much space, also need more knowledge to be able to understand deeply.

IRQ structure
    • The hardware Device controller interrupts the CPU through an IRQ line and can block interrupts by disabling an IRQ line.
    • Disabled interrupts are not lost and interrupts are sent to the CPU after the IRQ is activated
    • Activate/disable IRQ lines! = Shielded interrupt Global shielded/unshielded
Summary

Day time, all in the process, today is mainly explained why the introduction of the process, a simple discussion of the user space and kernel space control flow, and discusses how the process in the kernel is implemented, which involves the knowledge of the queue, this question is not mentioned, it is necessary for the reader to learn the data structure, In short, the Linux kernel needs a good knowledge of data structure, and finally also roughly covers the terminal anomaly, in short, the feeling process is a big bone, speaking very general, but also need a lot of time to learn, and analysis of the Linux kernel source code, in short, continue to refuel ~

All rights reserved, reprint please specify reprint address: http://www.cnblogs.com/lihuidashen/

    • This article is from: Linux Learning Network

10 days the second day of learning the Linux kernel---process

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.