Can linux create multiple processes


Most people don’t quite understand the knowledge points of this article on whether linux can create multiple processes, so the editor summarizes the following content for you. The content is detailed, the steps are clear, and it has certain reference value. I hope you can read it. This article can be rewarding, let's take a look at this article on whether linux can create multiple processes.

Linux can create multiple processes. Linux supports multiple processes and can handle multiple tasks at the same time to maximize the use of system resources. Communication methods between linux processes: 1. Use unnamed pipes; 2. Use well-known pipes (FIFO); 3. Use signal single; 4. Use shared memory; 5. Use message queues; 6. Use semaphores.

Linux can create multiple processes.

Linux supports multiple processes. One of the benefits of a multi-process system is that it can handle multiple tasks at the same time to maximize the use of system resources.

Chapter 1 Introduction to Linux Multi-Process

1.1 Overview

1.1.1 Process Concept< /h4>

In linux, a running program is called a process.
Program: static concept, it is a compiled binary file
Process: dynamic concept, when the program is running, the system will Automatically run a corresponding process
The process includes three parts: process control block (PCB), code segment, and data segment
Process control block: a structure is used in linux To represent, record the status information of the process
Zombie process: the parent process exits before the child process
If you create a child process, but the child process is not recycled in the parent process resources of the process, then the child process will become a zombie process, and the zombie process will eventually be recycled by a process called INIT in the system.
The init process (process No. 1) is the first process that runs when the system starts, and is the ancestor process of all processes.

1.1.2 Process view shell command

  • top View dynamic process information

  • ps -ef View process details

  • pstree Display process information in a tree format

  • bg Put the suspended process Run in the background

1.2 Process running status

1.2.1 Running status

  • Execution state (RUNNING): The process is occupying the CPU.

  • Ready state (RUNNING): The process is in the waiting queue waiting for scheduling.

  • Light sleep (INTERRUPTABLE): At this time, the process is waiting for the occurrence of an event or some kind of system resource, and can respond to the signal.

  • Deep sleep (UNINTERRUPTABLE): At this time, the process is waiting for an event to occur or some kind of system resource, and cannot respond to the signal.

  • Stop state (STOPPED): The process is suspended at this time.

  • Zombie state (ZOMBIE): At this time, the process cannot be scheduled, but the PCB has not been released.

  • DEAD: This is a terminated process and the PCB will be released

1.2.2 User state/kernel state

Kernel state: also called kernel space, which is the area where kernel processes/threads are located. Mainly responsible for operating system and hardware interaction.
User Mode: Also called User Space, it is the area where user processes/threads are located. Mainly used to execute user programs.


1. Difference
Kernel mode: The running code is not subject to any restrictions, and the CPU can execute any instruction.
User mode: CPU cannot be scheduled, and hardware cannot be accessed directly. The running code needs to be checked by the CPU a lot, and cannot directly access kernel data and programs, that is, it cannot access any valid address like a kernel-mode thread.

When the operating system executes user programs, it mainly works in the user state, and only switches to the kernel state when it performs tasks that it does not have permission to complete.

2. Distinguish between user mode and kernel mode reasons

  • Protection mechanism to prevent user processes from misoperation or malicious damage to the system< /p>

  • Ensure the centralized management of resources and reduce resource conflicts.

3. Switch from user mode to kernel mode
(1) System call (active)
The system call (system call) is the interface provided by the operating system to the user process to request the operating system to perform some privileged operations, that is, the window that provides services for the user process. Under Linux, you can use the man syscalls command to view all system call API interfaces provided by Linux.
Because the user mode cannot complete certain tasks, the user mode will request to switch to the kernel mode, and the kernel mode completes the switch through interrupts specially opened for users.

(2) Peripheral device interrupt (passive)
The peripheral device sends out an interrupt signal. When the interrupt occurs, the currently running process is suspended, and the operating system kernel For interrupt process processing, if the CPU executes the user mode program before the interrupt, it is equivalent to switching from the user mode to the kernel mode.
Interrupts are used to ensure that CPU control is handed over to the operating system, so that the operating system can perform certain operations.

(3) Abnormal (passive)
Some unknown exceptions occur when executing user programs, which will switch from user programs to the kernel The program that handles the exception is switched to the kernel state.

1.3 Process interface function

1.3.1 Process creation fork/vfork

1, fork(), vfork()< br/> (1) The newly created process is called a child process, which copies all the resources of the parent process (only once at the time of creation, the value of the global variable will be different in the future), the parent and child process who Who comes first is uncertain.

#includepid_t fork(void); Return value: > 0 means it is in the parent process. The return value at this time is **child process process id number** == 0 means in the process of the child < 0 Error creating process         #include#includepid_t vfork(void);

(2)**vfork()**The child process shares all the resources of the parent process, It must be the child process first run, and then the parent process runs (even if you add sleep() to artificially interfere, it is useless)
(3) Note
The use of exit() in the child process is completely different from the result of not using it Not the same
Whether sleep() is used in the parent-child process to give up the cpu time slice is also different
Whether wait() is used in the parent process, the result of waitpid() is also different

< p>

(4) Process switching execution

1.3.2 Process exit exit/_exit

1 , exit(), _exit()

#includevoid exit(int status); void _exit(int status); Parameters: Status ---> Status when the process exits The status can be agreed by yourself in the actual writing of the program: For example: exit(2)----"Open file error occurred                                                                              ,  Exit(0)----"Exit normally return: void the difference: Exit() will refresh the IO buffer when exiting, and then exit (responsible exit) _exit() Exit directly (irresponsible exit)

1.3.3 Wait for the child process to exit (the parent process recycles resources) wait/waitpid

1. wait()

#includepid_t wait(int *stat_loc); Return value: the id number of the child process you recycled Parameters: stat_loc -- "Save the status information when the child process exits (not just the return value) stat_loc not only saves the value when the exit exits, but also saves which signal the child process exits when it exits. What is the reason for the error.

2, waitpid()

pid_t waitpid(pid_t pid, int *stat_loc, int options); recycle child process/process group Parameters: pid ---- "You specify the id of the child process to be recycled                                                                                                                                                                              back  ==0 Wait for a child process in this process group to exit > 0 Waiting for the process whose PID is pid stat_loc-----"Store the exit status of the child process (can be NULL) options ----"Generally set to 0 WNOHANG returns immediately when there are no child processes WUNTRACED returns immediately when a child process is suspended WCONTINUED returns immediately when a child process receives SIGCONT Return value: -1 Execution failed > 0 success The return value is the PID of the recycled process 0 WNOHANG is specified, and there is no exited child process

1.3.4 Get process id–getpid

( 1) Get your own id getpid() #includepid_t getpid(void); Return value: the id number of the process (2) Get the parent process id getppid() #includepid_t getppid(void); Return value: the id number of the parent process

Chapter 2 Linux multi-process communication method

Whether it is communication between processes or communication between threads. It is nothing more than to solve a problem: the allocation of shared resources (coordinating the access of different processes/threads to shared resources)

2.1 Communication methods between processes

1. Traditional interprocess communication method

  • Unnamed pipe

  • Famous pipe

  • Signal

2, System V IPC object

  • Shared memory

  • Message queue

  • Semaphore

3, BSD< /p>

  1. Network socket (socket)

2.1.1 Anonymous pipe

1. Features : The most primitive way of communication between processes
It can only communicate between processes with affinity (parent-child process, sibling process);
It has no name (it exists );
Can be created in the sharing between linux and windows (there is no pipeline file generated at all), but the well-known pipe cannot be created (generated pipeline file);
Half-duplex communication.

2. Use of unnamed pipes
(1) Create pipe()

#includeint pipe(int fildes[2]); Parameters: fildes[2] contains two file descriptors fildes[0], fildes[1] fildes[0] read end   fildes[1] write end Return value: return 0 on success, return -1 on failure

(2) send and receive pipe information

myid = fork(); //Create child process if(myid == 0) { write(fd[1],"dad,thanks!",20); //The child process sends a message to the parent process close(fd[1]); close(fd[0]); exit(0); } else if(myid > 0) { read(fd[0],buf,20); //The parent process is blocked to receive messages from the child process printf("buf is:%s\n",buf); close(fd[1]); close(fd[0]); }

2.1.2 Famous pipe (FIFO)

1. Features: between any two processes

  • Cannot be created in the share between linux and windows;

  • Guarantee the atomicity of writing (atomicity: either do not do it, do it once The tone is finished without external interference);

  • The well-known pipelinecannot be overridden and created (general generationUse the access() function in the code to determine whether it exists, if there is already a pipeline with the same name, it cannot be created again);

  • Remember to close it after use;

  • When the pipe is opened as read-only, it will block until another process opens the pipe as write-only, then It is not blocked; if it is opened in a readable and writable manner, it will not be blocked.

  • Full-duplex communication, half-duplex.

2. Use of famous pipes
(1) Create mkfifo()

#include#includeint mkfifo(const char *pathname, mode_t mode); Parameters: pathname The path name of the named pipe mode: permission 0666 Return value: 0 success -1 Failed

(2) FIFO process information sending and receiving

fifo_read.c :------- ---》 #define FIFO1 "myfifo1" #define FIFO2 "myfifo2" int main(void) { int my_fd,fd1,fd2; char r_buff[30]; char w_buff[30]; bzero(r_buff,30); if(access(FIFO1,F_OK)==-1) { my_fd = mkfifo(FIFO1,0664); //create pipeline 1 if(my_fd == -1) { perror("failed!\n"); return -1; } } if(access(FIFO2,F_OK)==-1) { my_fd = mkfifo(FIFO2,0664); //create pipeline 2 if(my_fd == -1) { perror("failed!\n"); return -1; } } fd1 = open(FIFO1,O_RDONLY); //Open pipe 1 for read-only, get the pipe file descriptor if(fd1==-1) { the pricentf("open fifo1 file failed!\n"); exit(0); } fd2 = open(FIFO2,O_WRONLY); //Open pipe 2 for writing only, get the pipe file descriptor if(fd2==-1) { printf("open fifo2 file failed!\n"); exit(0); } while(1) { bzero(r_buff,30); read(fd1,r_buff,sizeof(r_buff)); //Read the message of pipeline 1 printf("client receive message is: %s\n",r_buff); printf("client please input a message!\n"); fgets(w_buff,30,stdin); write(fd2,w_buff,30); //Send information to pipeline 2 } close(fd2); close(fd1); return 0; } fifo_write.c :-----------》 #define FIFO1 "myfifo1" #define FIFO2 "myfifo2" int main(void) { int my_fd,fd1,fd2; char w_buff[30]; char r_buff[30]; bzero(w_buff,30); if(access(FIFO1,F_OK)==-1) { my_fd = mkfifo(FIFO1,0664); if(my_fd == -1) { perror("failed!\n"); return -1; } } if(access(FIFO2,F_OK)==-1) { my_fd = mkfifo(FIFO2,0664); if(my_fd == -1) { perror("failed!\n"); return -1; } } fd1 = open(FIFO1,O_WRONLY); if(fd1==-1) { printf("open fifo1 file failed!\n"); exit(0); } fd2 = open(FIFO2,O_RDONLY);if(fd2==-1) { printf("open fifo2 file failed!\n"); exit(0); } while(1) { bzero(w_buff,30); printf("server please input a message!\n"); fgets(w_buff,30,stdin); write(fd1,w_buff,strlen(w_buff)); //write message to pipeline 1 file read(fd2,r_buff,30); //Read information from pipeline 2 printf("server receive message is:%s\n",r_buff); } close(fd1); close(fd2); return 0; }

2.1.3 Signal single

When the program (process) is running, the outside world will send a signal to the program from time to time. The program is faced with two choices:
Ignore it (blocking/ignoring)
Blocking: refers to suspending the signal and waiting until the program is finished running before responding
Ignoring: discarding the signal
/> Respond to it

1. What are the signals in linux: kill -l view


(1) Signals 1 to 31 are called non-real-time signals: queues are not supported (if multiple signals come at the same time, the response Irregular)
(2) User-defined signals 10) SIGUSR1 12) SIGUSR2
(3) Signals 34 to 64 are called real-time signals: support queues, which are added later in the Linux system
Signals are similar to interrupts: hardware and software
There are two special signals above: SIGKILL, SIGSTOP cannot be ignored, nor can they be blocked

2 , Signal-related operation functions
(1) Send signal kill()

#includeint kill(pid_t pid, int sig); Parameters: pid ----"process id Positive number: the process number of the process to receive the signal 0: The signal is sent to all processes in the same process group as the pid process -1: The signal is sent to all processes in the process table (except the process with the largest process number) sig ----"signal name Return value: 0 success -1 Error

(2) Signal capture signal()

#includevoid (*signal(int sig, void (*func)(int)))(int); //SIGKILL Parameters: sig ---- "The signal you need to capture void (*func)(int) ----"Function pointer, callback function, call the function when the corresponding signal is captured; the second parameter can pass a function pointer, you can also use the following two macros definition:         SIG_IGN ----> The signal you caught will be ignored          SIG_DFL----- "The signal you capture will respond in the system's default way Return value: success: set the previous signal processing method Error: -1

(3) Waiting for signal pause()

#includeint pause(void); Return value: -1 Set the error value to EINTR 0 Success

(4) Signal blocking
Each process has its own signal mask (that is, the process is running The signals that will be blocked are called signal masks).
A series of functions about signal mask operation:

#includeint sigemptyset(sigset_t *set): Clear signal mask   int sigfillset(sigset_t *set): Add all signals to the signal mask   int sigaddset(sigset_t *set, int signum): add a specific signal to the signal mask int sigdelset(sigset_t *set, int signum): delete a specific signal from the mask int sigismember(const sigset_t *set, int signum): determine if a signal is in the mask Parameters: sigset_t ---- "store the signal blocked by the process

(5) Configure the signal mask sigprocmask()—block or unblock the signal

< p>

#includeint sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrictoset) Parameters: How --- "SIG_BLOCK Add the signal contained in the set to the original signal mask         SIG_SETMASK Use set to replace the original signal mask         SIG_UNBLOCK removes the signal contained in the set from the original mask set ---> new signal mask   oset --- "Original signal mask The signal mask in the original process includes: SIGINT , SIGCONT

(6) Capture the specified signal and obtain the signal carrying information sigaction()

#includeint sigaction(

int sig, const struct sigaction *restrict act, struct sigaction *restrict oact); parameter: 

sig --- "The signal you want to capture 

Act---"The response function corresponding to the signal you need to capture is defined in this structure 

oact --- "Original 

struct sigaction { void(*) (int) sa_handler ----" signal response function                       

sa_mask --- "the mask of the signal int sa_flags ----" SA_SIGINFO    void(*) (int, siginfo_t * , void )---"signal response function } sa_flags ---" equal to SA_SIGINFO, then the response function of the signal is void(*) (int, siginfo_t * , void ) If not equal, then the response function of the signal is void(*) (int) 

siginfo_t---"/usr/include/i386-linux-gnu/bits/siginfo.h saves the status information of the signal, the label of the signal, the id of the process that sent the signal, etc.

Copyright Description:No reproduction without permission。

Knowledge sharing community for developers。

Let more developers benefit from it。

Help developers share knowledge through the Internet。

Follow us