Linux multi-process learning and Linux Process Learning
1Linux Process Overview a process is a process executed once by a program. It is essentially different from a program. The program is static. It is a set of commands stored on disks in sequence. A process is a dynamic concept. It is a program of a runner, including the dynamic creation, scheduling, and elimination of processes. It is the basic scheduling unit of Linux. A process control block (PCB) is a static description of a process, including the process description, process control information, and resource information time slice: he takes turns at the time slice obtained by each process and then takes thousands of control from the process.
1.1 Process Identity OS will assign a unique prevalent ID to each process as the process'sID (pid) and parent process ID (ppid)The ancestor of all processes is the same process.Init process, ID is 1 throughGetpid (), getppid ()Obtain the pid of the Process, ppid instance: printf ("pid: % d ppid: % d \ n", getpid (), getppid ());
1.2 process user ID and group ID
The process must have a user-like identity. The user is the identity of the user and the user group is available.Getuid (), getgid ();The obtained process also has a valid user ID and valid group ID. If it is missing, it is the same as the real ID.Geteuid (), getegid ();When the File Permission is S, the valid ID is the owner (creator) of the process)Otherwise, the valid ID is the program operator, which is the same as the real ID.
Ps-aux: view the permissions, cpu, and memory usage of all user processes
Ps-ef: View user operation PID and PPID and CMD (command line)
1.3 Process statusExecution state, ready state, waiting state
1.4LInux process structure the process in Linux contains three segments: Data Segment, code segment, and stack segment data segment: (Common Data Segment) global variable, Changshu (bbs data segment) code segment of the data space allocated for the initialized global variables and (HEAP) Dynamic Data: The data stack segment that stores the program code: the return address of the subroutine, the parameters of the subroutine, and the local variables of the program
Process Management in 1.5LInux
Process: Minimum OS Unit 1) ps view active process 2) ps-aux view all processes % cpu, % mem stat status (S sleep T pause R run Z botnet) 3) ps-aux | grep 'A' search for the specified (aa) process 4) ps-ef can be a real parent-child relationship and Issue 5) top 20 processes in reality, dynamic Change 6 ). /my_add may take a long time to run. You can press ctrl + z to pause Beijing. When you run the bg job ID, you can bring the process to the background for example: [1] +. /my_add 1 34 &, & indicates that the process is running in the background. Jods can be used to view the fg job ID of the background task to bring the background personnel to the foreground. 7) kill-9 process number (PID) kills the process and pkill a process name
2 Process Creation in Linux there are four types of sub-process creation functions: system (), fork (), exec * (), popen (); 2.1the system function in the brackets of the system function is a command, that is, the cmd example is as follows:
#include<iostream>#include<stdlib.h>#include<string.h>#include<stdio.h>using namespace std;int main(int argc,char *argv[]){char cmd[1024]="";for(int i=1;i<argc;i++){strcat(cmd,argv[i]);strcat(cmd," ");}puts(cmd);int ans;ans=system(cmd);printf("%x\n",ans);}
Use system to call other executable programs and enter parameters such :. /main. /my_add where my_add calculates the sum of the two numbers, and the calculation result is in the high byte of the returned value of system: ret00, so the result is 256
int main(int argc,char *argv[]){if(argc!=2){printf("failed\n");return 0;}int left,right;char cmd[1024]="";char line[1024]="";strcat(cmd,argv[1]);strcat(cmd," ");while(printf(">>"),scanf("%d %d",&left,&right)){memset(line,0,sizeof(line));sprintf(line,"%s %d %d",argv[1],left,right);strcpy(cmd,line);int ret;ret=system(cmd);printf("result:%d\n",ret/256);}}
2.2fork: the fork function creates a new process in an existing process. The new process acts as a sub-process. The returned value of the original process as the parent process is a sub-process, the returned value of the sub-process is 0. fork creates a sub-process to completely replicate the parent process, and the buffer also copies the meta-process and the sub-capital are returned from the fork function, and continues the circle in each of them, however, the fork return value of the meta-function is the pid of the sub-process, while the fork returns 0 in the sub-process, and the return value-1 indicates that the creation failed.
# Include <iostream> # include <unistd. h> # include <stdlib. h> # include <stdio. h> using namespace std; int main (int argc, char * argv []) {pid_t pid; int I = 3; printf ("hello \ n "); pid = fork (); fflush (stdout); // when the son copies, the buffer is also copied. Otherwise, if (pid> 0) {printf ("parents: pid: % u, ret: % u, pp: % u \ n", getpid (), pid, getppid ();} else if (pid = 0) {// sleep (5); printf ("child: pid: % u, ret: % u, pp: % u \ n ", getpid (), pid, getppid ();} printf (" bye! \ N ");}
2.3exec: the exec function uses the program specified by the first exec parameter to overwrite the existing process space. That is to say, after the exec family function is executed, all the code after him will not execute detailed usage. Enter man execint execl (const char * path, const char * arg,...) on the terminal ,...);
Int execlp (const char * file, const char * arg ,...);
Int execle (const char * path, const char * arg,..., char * const envp []);
Int execv (const char * path, char * const argv []);
Int execvp (const char * file, char * const argv []);
Int execvpe (const char * file, char * const argv [], char * const envp []);
Path contains the full path name of the execution file name. When multiple parameters are specified, note that the last parameter must be NULL, and arg is the command line parameter of the executable file.
Int execl (const char * path, const char * arg,...); example:
if(execl("/home/yang/0820/my_exec/","my_add","3","2",NULL)==-1){perror("execl error");}
Int execlp (const char * file, const char * arg,...); example:
if(execlp("./my_add","my_add","fwef","fwe","fewgeraf",NULL)==-1){perror("execlp error");}
Int execv (const char * path, char * const argv []); for example:
char *args[10];args[0]="my_add";args[1]="12";args[2]="23";args[3]=NULL;if(execv("/home/yang/0820/my_exec/my_add",args)==-1){perror("execl:");}
The 2.4popen function (to be supplemented later) is similar to the system function. Unlike the system function, the popen function uses pipelines for operations. The prototype is # include <stdio. h>
FILE * popen (const char * command, const char * type );
Int pclose (FILE * stream );
The command is the full path and execution parameter of the executable file. The type optional parameter is "r" or the file returned by the invalid wpenpenpopenis a standard input stream (for example, my_add.exe, that is, the file stream returned by the stdin "r" popen is used as the standard output stream of the new process stdout. That is to say, the popen only changes the detailed process of the standard input stream or standard output stream popen of the new process: the type is "r" (that is, the execution result of the command is used as the input result of the current process). The calling program uses the popen function to return the FILE * FILE stream pointer, you can use common stdio libraries such as fgets to read the output of the called function. If the type is "w" (that is, the output result of the current program is used as the input of the commend command), the caller can use fwrite to call the program to send data, the called program can read the data from its own standard input. Example: the screen output of the main program:
FILE * fp; char a [1000]; char B [1000]; char cmd [1024] = ""; printf ("plseas write \ n"); fgets (, 1000, stdin); sprintf (cmd, "% s", argv [1], a); fp = popen (cmd, "r "); // The command cmd is the executable file path fgets (B, 1000, fp); printf ("% s \ n", B );
New process screen output:
FILE *fp;char a[1000];gets(a);fp=popen(argv[1],"w");fputs(a,fp);pclose(fp);
3. Process Control and termination when a sub-process is started using the fork function, the sub-process has its own life to run independently.
Orphan Process: If the parent process exits before the child process, the child process becomes an orphan process (usually the parent process is responsible for releasing the memory space of the child process ), at this time, it is automatically taken over by the process (init) with PID 1. After the orphan process exits, its cleanup is automatically handled by the ancestor process init.
Botnets: When a child process exits, the system does not automatically clean up the working environment of the child process. A parent process must call wait or waitpid to complete the cleaning. If the parent process does not clean up, once introduced, sub-processes will become zombie processes. If too many zombie processes exist in the system, the system performance function prototype will be affected: # include <sys/types. h> # include <sys/wait. h> pid_t wait (int * status); pid_t waitpid (pid_t pid, int * status, int options );
Wait FunctionsRandomly wait for a child process that has exited and return the pid of the child Process
WaitpidChild processes waiting for pid formulation. If the fire is-1, it indicates waiting for all child processes.
Status ParameterIs an outgoing parameter that stores the exit status of the sub-process.
OptionsIt is used to change the waitpid behavior. The most important one is WNOHANG. It indicates that a zombie process is returned immediately regardless of whether the child process exits. Example:
#include <stdio.h>#include <stdlib.h>#include <unistd.h>main(){ pid_t pid = fork(); if( pid == 0 ) { exit(10); } else {sleep(10); }}
Example of avoiding zombie processes:
# Include <stdio. h> # include <stdlib. h> # include <unistd. h> main () {pid_t pid = fork (); if (pid = 0) {exit (10) ;}else {wait (NULL ); // NULL indicates waiting for all processes to sleep (10); // usually put sleep behind wait, or a zombie process will appear }}
3.2 Process Termination 5 methods: 1) the main function naturally returns 2) the exit function is called 3) call the _ exit function to call the abort function. The difference between ctrl + c exit and _ exit signals that can lead to Process Termination is that exit processes the buffer content, and _ exit does not process the buffer content.
The prototype of the exit and _ exit functions:
# Include <stdlib. h> // exit header file
# Include <unistd. h> // _ exit header file
Void exit (int status );
Void_exit (int status );
Status is an integer parameter. You can use this parameter to pass the status of Process Termination. "0" indicates normal exit, "other" indicates an error, and the process ends abnormally.
How to Learn about linux?
To learn about linux, install the Fedora system by yourself, and configure your linux system by using commands according to the tutorial, here, why do you want to install the fedora system? It is because the system is mainly used for command operations, which allows you to get better training. After the system is installed, you only need to use this system to perform various operations, such as watching movies, listening to music, chatting, and so on. The premise is that you need to manually install these software on the linux source using commands, your linux knowledge is improved without knowing it. if you do not need to perform any operations, you should look for more tutorials. I don't think there is any step in this learning because your knowledge of linux has been continuously deepened when you are using linux. it makes no sense to copy a large article.
[Linux] multi-process Programming
# Include <stdio. h>
# Include <unistd. h>
# Include <stdlib. h>
# Include <string. h>
# Include <sys/types. h>
# Include <sys/wait. h>
Int main (void)
{
Int I = 0;
Int * nCount;
Int pfd [2];
Char szBuff [11] = {0 };
Int status;
Pid_t pid;
Pipe (pfd );
If (fork () = 0)
{
NCount = malloc (sizeof (int) * 10 );
For (I = 0; I <10; ++ I)
{
NCount [I] = I;
Sprintf (szBuff, "% s % d", szBuff, nCount [I]);
}
Write (pfd [1], szBuff, strlen (szBuff ));
Free (nCount );
Close (pfd [0]);
Close (pfd [1]);
}
Else
{
If (fork () = 0)
{
Printf ("sleep (5 )! \ N ");
Sleep (5 );
Read (pfd [0], szBuff, 10 );
Printf ("% s \ n", szBuff );
Close (pfd [0]);
Close (pfd [1]);
}
Else
{
Pid = wait (& status );
I = WEXITSTATUS (status );
Printf ("child is % d, exit status = % d \ n", pid, I );
Pid = wait (& status );
I = WEXITSTATUS (status );
Pr ...... remaining full text>