Detailed linux process: fork process, orphaned, zombie process (to be re-transfer map)

Original link: https://blog.csdn.net/xungjhj/article/details/77695887

https://blog.csdn.net/xungjhj/article/details/77695887

This section objectives:

  • Copy process image
  • fork system call
  • Orphaned, zombie
  • When writing copy

First, the process of copying (or generate)

     Use the fork function to get the child to inherit from the entire process's address space of the parent process, including: process context, process stack, memory information, open file descriptors, signal control settings, process priority, process group number, current job directory, the root directory, resource limitations, and other control terminal.

The difference between child and parent processes that:

1, the parent lock set, the child process does not inherit (because if it is exclusive lock, inherited words, a contradiction)

2, each of a different process ID and parent process ID

3, pending alarm child process is cleared;

4, pending signal set of the child process is set to the empty set.

Two, fork system call

Contains header <sys / types.h> and <unistd.h>

Function: to create a child process

Function prototype

pid_t fork (void); // call returns a value twice, in their return to the address space, which means there are now two different basic processes in execution

Parameters: No parameters.

return value:

  • If you successfully create a child process is returned to the parent process child process ID
  • If you successfully create a child process, the child process is returned to a value of 0
  • If the creation of -1 indicates a failure

flow chart:

 

 

Parent process calls fork () system call, and then into the kernel, a copy process, if successful:

1, then the process that is calling for the return value of the parent process child process pid just created, because no child processes information PCB process, the parent process can only be obtained through this.

2, a child process (new process just created), 0 returns,

At this time there are two processes in execution then down

If it fails, 0 is returned, the calling process to continue down

Note: fork English meaning: the child branch, fork system call copy produced by the parent process (the calling process) is basically the same: a code segment + data segment + stack segment + PCB, the current operating environment is basically the same, so the child process after fork started down, but not executed from the beginning.

The sample program:

 

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

#define ERR_EXIT(m) \
    do\
    {\
        perror(m);\
        exit(EXIT_FAILURE);\
    }\
    while (0)\

int main(void)
{
    pid_t pid;
    printf("before calling fork,calling process pid = %d\n",getpid());
    pid = fork();
    if(pid == -1)
        ERR_EXIT("fork error");
    if(pid == 0){
        printf("this is child process and child's pid = %d,parent's pid = %d\n",getpid(),getppid());
    }
    if(pid > 0){
        //sleep(1);
        printf("this is parent process and pid =%d ,child's pid = %d\n",getpid(),pid);
    }

    return 0;
}

 

operation result:

 

When not to the parent process did not increase sleep, because the parent process before executing the child process orphaned process, the system will give its Tuogu 1 (init) process,

Therefore ppid = 1.

When coupled with sleep, before executing the child process:

 

The desired results can be seen properly.

Third, the orphaned, zombie

After the fork system call, the parent and child will alternate execution, execution order uncertain.

If the parent process exits first, the child did not quit then the parent process the child process will change the init process (Tuogu to the init process). (Note: Any process must have a parent process)

If the child process exits first, the parent process has not quit, then the child must capture until the parent process to exit status of the child process really ended, or else this time the child becomes stiff process (zombie process: retaining only some of the exit information for parent process queries)

Example:

 

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

#define ERR_EXIT(m) \
    do\
    {\
        perror(m);\
        exit(EXIT_FAILURE);\
    }\
    while (0)\

int main(void)
{
    pid_t pid;
    printf("before calling fork,calling process pid = %d\n",getpid());
    pid = fork();
    if(pid == -1)
        ERR_EXIT("fork error");
    if(pid == 0){
        printf("this is child process and child's pid = %d,parent's pid = %d\n",getpid(),getppid());
    }
    if(pid > 0){
        sleep(100);
        printf("this is parent process and pid =%d ,child's pid = %d\n",getpid(),pid);
    }

    return 0;
}

 

The above procedure is consistent with that earlier, it is to make the parent sleep 100 seconds, so that the child process to exit

operation result:

 

As can be seen, the first child process exits, but the process can also view the list of sub-processes, [a.out] <defunct>, the meaning of death, that zombie process, if the system there are too many zombie processes, will It will make the new process can not produce.

 

Fourth, write copy

linux system in order to improve system performance and resource utilization, while fork a new process, the system does not really make a copy.

If more than one process to read their own copy of that part of the resources, then the copy is unnecessary.

Each process just to save a pointer to the resources on it.

If a process to modify their share of resources "copy", then it will copy the share of resources. This is the meaning of copy-on-write

fork 和vfork:

Prior to fork yet implemented copy on write. Unix designers immediately after the fork are very concerned about the implementation of address space caused by waste exec, so the introduction of vfork system call.

vfork there is a limit, the child process must be performed _exit or exec function immediately.

Even fork to achieve a copy write, efficiency is not high vfork, but we do not recommend the use of vfork, because almost every realization of a vfork are more or less there are some problems on

vfork:

Linux Description 
    vfork(), just like fork(2), creates a child process of the calling pro- 
    cess.  For details and return value and errors, see fork(2).

    vfork()  is  a special case of clone(2).  It is used to create new pro- 
    cesses without copying the page tables of the parent process.   It  may 
    be  useful  in performance-sensitive applications where a child will be 
    created which then immediately issues an execve(2).

    vfork() differs from fork(2) in that the parent is suspended until  the 
    child  terminates (either normally, by calling _exit(2), or abnormally, 
    after delivery of a fatal signal), or it makes  a  call  to  execve(2). 
    Until  that point, the child shares all memory with its parent, includ- 
    ing the stack. The child must not return from the current function  or 
    call exit(3), but may call _exit(2).

    Signal  handlers  are inherited, but not shared.  Signals to the parent 
    arrive after the child releases the parent’s memory  (i.e.,  after  the 
    child terminates or calls execve(2)).

 

The sample program:

 

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

#define ERR_EXIT(m) \
    do\
    {\
        perror(m);\
        exit(EXIT_FAILURE);\
    }\
    while (0)\

int main(void)
{
    pid_t pid;
    int val = 1;
    printf("before calling fork, val = %d\n",val);
    
    //pid = fork();
    pid = vfork();
    if(pid == -1)
        ERR_EXIT("fork error");
    if(pid == 0){
        printf("chile process,before change val, val = %d\n",val);
        val++;
        //sleep(1);
        printf("this is child process and val = %d\n",val);
        _exit(0);

    }
    if(pid > 0){
        sleep(1);
        //val++;
        printf("this is parent process and val = %d\n",val);
    }

    return 0;
}

 

When you call fork:

operation result:

 

Known copy-on-write

When vfork but the child did not use the exit to exit:

 

The results wrong,

Use vfork and exit Exit:

 

The result is normal, the parent and child share

 

After the fork parent and child share files:

 

 

Fork a child process generates the same parent file points to the same file descriptor table, a reference count increases, the shared file offset pointer

The sample program:

 

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>

#define ERR_EXIT(m) \
    do\
    {\
        perror(m);\
        exit(EXIT_FAILURE);\
    }\
    while (0)\

int main(void)
{
    pid_t pid;
    int fd;
    fd = open("test.txt",O_WRONLY);
    if(fd == -1)
        ERR_EXIT("OPEN ERROR");
    pid = fork();
    if(pid == -1)
        ERR_EXIT("fork error");
    if(pid == 0){
        write(fd,"child",5);
    }
    if(pid > 0){
        //sleep(1);
        write(fd,"parent",6);
    }

    return 0;
}

 

operation result:

 

After his son found the process of sharing the file offset pointers, finished file offset after the parent process the child process to the parent and then start writing.

Guess you like

Origin blog.csdn.net/happylzs2008/article/details/102769418