Advanced Linux Program Design chapter 3: Process

Source: Internet
Author: User
Document directory
  • Each process has a unique process ID.
  • Each process has a parent process.
  • Processes in the system are organized in the form of a tree. The init process (process number 1) serves as the root.
  • Process 0 is a scheduling process. It does not correspond to any program and is part of the kernel.
  • Process 1 is the init process, which is started by the kernel in the system startup phase. It corresponds to the/sbin/init program and is a common user process.
  • In the program, you can get the process number through getpid () and get the process Number of the parent process through getppid.
  • Run the ps command to obtain all processes running in the system.
  • The kill command can be used to kill a process.
  • The system function provides a simple method to run a command in a program.
  • When the program calls fork, a fully copied subroutine is created.
  • The parent process continues from where fork is called.
  • Sub-processes also run from the same place.
  • The Return Value of the fork function in the parent process is the process number of the child process.
  • The Return Value of the fork function in the sub-process is zero.
  • The exec function replaces the currently running process with another program.
  • Exec functions are a group of functions:
  • The parameter received by the function (execvp, execlp) that contains p is the program name.
  • Parameters received by functions that do not contain p are the full path of the program.
  • Functions that contain v (execv, execvp, execve) receive parameter lists in arrays.
  • Functions that contain l (execl, execlp, execle) receive the parameter list in the form of a list.
  • Execve (execle) functions that contain e receive environment variables in an array.
  • A signal is a special message sent to a process.
  • When a process receives a signal, it immediately processes the signal and does not wait until the current function call or even a line of code is completed.
  • The system sends a signal to the process in special circumstances:
  • SIGBUS: Bus Error
  • SIGSEGV: Segment Violation
  • SIGFPE: Floating Point Number exception
  • A process can send signals to another process.
  • You can send SIGTERM and SIGKILL signals to end a process.
  • Signals can be used to send commands to a process. There are two types of user-defined signals: SIGUSER1 and SIGUSR2
  • The sigaction function sets the signal processing method.
  • SIG_DFL indicates that the default signal processing method is used.
  • SIG_IGN indicates that this signal can be ignored.
  • The second parameter is the sigaction struct, which includes a signal processing function.
  • Because signal processing is asynchronous, do not call I/O operations in signal processing functions, or call libraries or system functions.
  • The signal processing function should process the least things as much as possible.
  • The signal processing function may also be interrupted by another signal.
  • If you want to operate a global variable in the signal processing function, this variable should be of the sig_atomic_t type.
  • A process can end in two ways:
  • The process itself calls the exit function, or its main function ends.
  • The process ends abnormally after receiving the signal.
  • Ctrl + c send SIGINT Signal
  • Kill command to send SIGTERM Signal
  • The abort function sends the SIGABRT signal.
  • The SIGKILL function immediately ends a process. The signal cannot be blocked and is processed by the program itself.
  • All these signals can be sent using the kill command.
  • The kill function can be used to send signals to a process in a program.
  • Wait functions:
  • The wait function blocks the current process until one of the Child processes ends.
  • The waitpid function waits for a specified sub-process to end.
  • The wait3 function waits for the child process to end and returns statistics on various resource usage of the child process.
  • The wait4 function waits for a specific sub-process to end and returns statistics on various resource usage of the sub-process.
  • The so-called zombie process refers to a process that has ended but resources have not been recycled.
  • The parent process has the responsibility to use the wait function to reclaim the resources of the child process when the child process ends.
  • When a child process has not been recycled by the parent process, it exists as a zombie process in the system.
  • When a program ends, all its sub-processes are inherited by a special process (init process. The init process is responsible for revoking all the dead sub-processes it inherits.
  • When a child process ends, it sends a SIGCHID signal to its parent process.
  • A process can recycle sub-processes by processing the SIGCHID signal.
  • Each process has a unique process ID.
  • Each process has a parent process.
  • Processes in the system are organized in the form of a tree. The init process (process number 1) serves as the root.
    • Process 0 is a scheduling process. It does not correspond to any program and is part of the kernel.
    • Process 1 is the init process, which is started by the kernel in the system startup phase. It corresponds to the/sbin/init program and is a common user process.
  • In the program, you can get the process number through getpid () and get the process Number of the parent process through getppid.

 

# Include <stdio. h>

# Include <unistd. h>

Int main ()

{

Printf ("The process ID is % d \ n", (int) getpid ());

Printf ("The parent process ID is % d \ n", (int) getppid ());

Return 0;

}

  • Run the ps command to obtain all processes running in the system.
  • The kill command can be used to kill a process.
1. Create process 1.1 and system functions
  • The system function provides a simple method to run a command in a program.

 

# Include <stdlib. h>

Int main ()

{

Int return_value;

Return_value = system ("ls-l /");

Return return_value;

}

1.2. fork and exec Functions
  • When the program calls fork, a fully copied subroutine is created.
  • The parent process continues from where fork is called.
  • Sub-processes also run from the same place.
  • The Return Value of the fork function in the parent process is the process number of the child process.
  • The Return Value of the fork function in the sub-process is zero.

# Include <stdio. h>

# Include <sys/types. h>

# Include <unistd. h>

Int main ()

{

Pid_t child_pid;

Printf ("the main program process ID is % d \ n", (int) getpid ());

Child_pid = fork ();

If (child_pid! = 0 ){

Printf ("this is the parent process, with id % d \ n", (int) getpid ());

Printf ("the child's process ID is % d \ n", (int) child_pid );

}

Else

Printf ("this is the child process, with id % d \ n", (int) getpid ());

Return 0;

}

  • The exec function replaces the currently running process with another program.
  • Exec functions are a group of functions:
    • The parameter received by the function (execvp, execlp) that contains p is the program name.
    • Parameters received by functions that do not contain p are the full path of the program.
    • Functions that contain v (execv, execvp, execve) receive parameter lists in arrays.
    • Functions that contain l (execl, execlp, execle) receive the parameter list in the form of a list.
    • Execve (execle) functions that contain e receive environment variables in an array.

# Include <stdio. h>

# Include <stdlib. h>

# Include <sys/types. h>

# Include <unistd. h>

/* Spawn a child process running a new program. PROGRAM is the name of the program to run; the path will be searched for this program. ARG_LIST is a NULL-terminated list of character strings to be passed as the program's argument list. returns the process ID of the spawned process. */

Int spawn (char * program, char ** arg_list)

{

Pid_t child_pid;

/* Duplicate this process .*/

Child_pid = fork ();

If (child_pid! = 0)

/* This is the parent process .*/

Return child_pid;

Else {

/* Now execute PROGRAM, searching for it in the path .*/

Execvp (program, arg_list );

/* The execvp function returns only if an error occurs .*/

Fprintf (stderr, "an error occurred in execvp \ n ");

Abort ();

}

}

Int main ()

{

/* The argument list to pass to the "ls" command .*/

Char * arg_list [] = {

"Ls",/* argv [0], the name of the program .*/

"-L ",

"/",

NULL/* The argument list must end with a NULL .*/

};

/* Spawn a child process running the "ls" command. Ignore the returned child process ID .*/

Spawn ("ls", arg_list );

Printf ("done with main program \ n ");

Return 0;

}

 

2. Signal
  • A signal is a special message sent to a process.
  • When a process receives a signal, it immediately processes the signal and does not wait until the current function call or even a line of code is completed.
  • The system sends a signal to the process in special circumstances:
    • SIGBUS: Bus Error
    • SIGSEGV: Segment Violation
    • SIGFPE: Floating Point Number exception
  • A process can send signals to another process.
  • You can send SIGTERM and SIGKILL signals to end a process.
  • Signals can be used to send commands to a process. There are two types of user-defined signals: SIGUSER1 and SIGUSR2
  • The sigaction function sets the signal processing method.
    • SIG_DFL indicates that the default signal processing method is used.
    • SIG_IGN indicates that this signal can be ignored.
    • The second parameter is the sigaction struct, which includes a signal processing function.
  • Because signal processing is asynchronous, do not call I/O operations in signal processing functions, or call libraries or system functions.
  • The signal processing function should process the least things as much as possible.
  • The signal processing function may also be interrupted by another signal.
  • If you want to operate a global variable in the signal processing function, this variable should be of the sig_atomic_t type.

# Include <stdio. h>

# Include <signal. h>

# Include <string. h>

# Include <sys/types. h>

# Include <unistd. h>

Sig_atomic_t sigusr1_count = 0;

Void handler (int signal_number)

{

++ Sigusr0000count;

}

Int main (int argc, char * argv [])

{

Printf ("the process ID is % d \ n", (int) getpid ());

Struct sigaction sa;

Memset (& sa, 0, sizeof (sa ));

Sa. sa_handler = & handler;

Sigaction (SIGUSR1, & sa, NULL );

Int I = 0;

While (I <100)

{

Sleep (1 );

I ++;

}

Printf ("SIGUSR was raised % d times \ n", sigusr0000count );

Return 0;

}

Compile the above Code as the program sigusr1

Gcc-o sigusr1 sigusr1.c

Run the program

[Liuchao @ localhost Signal] $./sigusr1

The process ID is 3401

On another terminal, run the ps command to obtain the sigusr1 process number.

[Liuchao @ localhost ~] $ Ps-

PID TTY TIME CMD

3401 pts/1 00:00:00 sigusr1

3403 pts/3 00:00:00 ps

Send multiple sigusr1 signals to this process number

[Liuchao @ localhost ~] $ Kill-s SIGUSR1 3401

[Liuchao @ localhost ~] $ Kill-s SIGUSR1 3401

[Liuchao @ localhost ~] $ Kill-s SIGUSR1 3401

[Liuchao @ localhost ~] $ Kill-s SIGUSR1 3401

[Liuchao @ localhost ~] $ Kill-s SIGUSR1 3401

When the process ends

[Liuchao @ localhost Signal] $./sigusr1

The process ID is 3401

SIGUSR was raised 5 times

 

3. Process Termination
  • A process can end in two ways:
    • The process itself calls the exit function, or its main function ends.
    • The process ends abnormally after receiving the signal.
      • Ctrl + c send SIGINT Signal
      • Kill command to send SIGTERM Signal
      • The abort function sends the SIGABRT signal.
      • The SIGKILL function immediately ends a process. The signal cannot be blocked and is processed by the program itself.
  • All these signals can be sent using the kill command.

 

% Kill-KILL pid
  • The kill function can be used to send signals to a process in a program.
Kill (child_pid, SIGTERM );
  • Wait functions:
    • The wait function blocks the current process until one of the Child processes ends.
    • The waitpid function waits for a specified sub-process to end.
    • The wait3 function waits for the child process to end and returns statistics on various resource usage of the child process.
    • The wait4 function waits for a specific sub-process to end and returns statistics on various resource usage of the sub-process.

Int main ()

{

Int child_status;

/* The argument list to pass to the "ls" command .*/

Char * arg_list [] = {

"Ls",/* argv [0], the name of the program .*/

"-L ",

"/",

NULL/* The argument list must end with a NULL .*/

};

/* Spawn a child process running the "ls" command. Ignore the returned child process ID .*/

Spawn ("ls", arg_list );

/* Wait for the child process to complete .*/

Wait (& child_status );

If (WIFEXITED (child_status ))

Printf ("the child process exited normally, with exit code % d \ n", WEXITSTATUS (child_status ));

Else

Printf ("the child process exited abnormally \ n ");

Return 0;

}

  • The so-called zombie process refers to a process that has ended but resources have not been recycled.
  • The parent process has the responsibility to use the wait function to reclaim the resources of the child process when the child process ends.
  • When a child process has not been recycled by the parent process, it exists as a zombie process in the system.

# Include <stdlib. h>

# Include <sys/types. h>

# Include <unistd. h>

Int main ()

{

Pid_t child_pid;

/* Create a child process .*/

Child_pid = fork ();

If (child_pid> 0 ){

/* This is the parent process. Sleep for a minute .*/

Sleep (60 );

}

Else {

/* This is the child process. Exit immediately .*/

Exit (0 );

}

Return 0;

}

% Ps-e-o pid, ppid, stat, cmd

3824 2888 S +./zombie

3825 3824 Z + [zombie] <defunct>

  • When a program ends, all its sub-processes are inherited by a special process (init process. The init process is responsible for revoking all the dead sub-processes it inherits.
  • When a child process ends, it sends a SIGCHID signal to its parent process.
  • A process can recycle sub-processes by processing the SIGCHID signal.

# Include <signal. h>

# Include <string. h>

# Include <sys/types. h>

# Include <sys/wait. h>

Sig_atomic_t child_exit_status;

Void clean_up_child_process (int signal_number)

{

/* Clean up the child process .*/

Int status;

Wait (& status );

/* Store its exit status in a global variable .*/

Child_exit_status = status;

}

Int main ()

{

/* Handle SIGCHLD by calling clean_up_child_process .*/

Struct sigaction sigchld_action;

Memset (& sigchld_action, 0, sizeof (sigchld_action ));

Sigchld_action.sa_handler = & clean_up_child_process;

Sigaction (SIGCHLD, & sigchld_action, NULL );

/* Now do things, including forking a child process .*/

/*...*/

Return 0;

}

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.