2) Introduction to Linux programming--process Introduction to the creation of a process under Linux preface: This article is used to describe the various concepts that are related to processes under Linux. We will learn: the process of conceptual process of identity process creation of the daemon process1. The concept of the process Linux operating system is multi-user-oriented. At the same time, many users can issue various commands to the operating system. So how does the operating system achieve a multiuser environment??in modern operating systems, there is the concept of procedures and processes. So what is a program and what is a process??A popular speaking program is a file that contains executable code, and is a static file. The process is an instance of a program that starts execution but has not yet finished. is the implementation of executables. A program can have many processes, and each process can have many child processes. Loop down in turn, And the process of descendant generation. When the program is called into memory by the system, the system assigns a certain amount of resources (memory, device, and so on) to the program and then makes a series of complex operations that make the program a process for the system to invoke. In the system only process has no program, in order to distinguish between different processes, the system assigns each process an ID (like our Identity card) for identification. In order to make full use of the resources, the system also distinguishes the process from different states. Divide the process into new, run, block, ready, and complete five states. New indicates that the process is being created, that the running process is running, that the process is waiting for an event to occur, that the system is waiting for the CPU to execute the command, and that the completion indicates that the process has ended and that the system is reclaiming resources. For a detailed explanation of the five states of the process we can look at the operating system with detailed explanations. 2. Process flag above we know that the process has an ID, so how do we get the ID of the process??The system call Getpid can get the ID of the process, and getppid can get the ID of the parent process that created the process that called the function. #include<unistd>; pid_t Getpid (void); pid_t Getppid (void); The process is for the program, and the program is for the user Service. The system also establishes a connection for processes and users in order to find the user name of the process. This user is called the owner of the process. Each user also has a user ID. Through the system Call Getuid to get the ID of the owner of the process. Because the process uses some resources, and Linux protects the system resources, there is a valid user ID for the process to get a certain resource. This ID is related to the resource usage of the system and involves the permissions of the process. Through the system call Geteuid we can get a valid user ID for the process. and user ID The process also has a group ID and a valid group ID system call Getgid and Getegid can get the group ID and the valid group ID, respectively #include<unistd>; #include<sys/types.h>; uid_t Getuid (void); uid_t Geteuid (void); gid_t Getgid (void); git_t Getegid (void); Sometimes we are interested in other user information (login name, etc.), this time we can call Getpwui D to get it. structpasswd {Char*pw_name;/*Login Name*/ Char*PW_PASSWD;/*Login Password*/uid_t Pw_uid;/*User ID*/gid_t Pw_gid;/*User Group ID*/ Char*pw_gecos;/*the user's real name*/ Char*pw_dir;/*User's Directory*/ Char*pw_shell;/*User's Shell*/ }; #include<pwd.h>; #include<sys/types.h>; structpasswd *Getpwuid (uid_t uid); Let's learn an example to practice some of the functions we've learned above: #include<unistd.h>; #include<pwd.h>; #include<sys/types.h>; #include<stdio.h>; intMainintargcChar**argv) {pid_t my_pid,parent_pid; uid_t my_uid,my_euid; gid_t my_gid,my_egid;structpasswd *my_info; My_pid=getpid (); Parent_pid=getppid (); My_uid=getuid (); My_euid=Geteuid (); My_gid=Getgid (); My_egid=Getegid (); My_info=Getpwuid (My_uid); printf ("Process id:%ld\n", My_pid); printf ("Parent id:%ld\n", Parent_pid); printf ("User id:%ld\n", My_uid); printf ("effective User id:%ld\n", My_euid); printf ("Group id:%ld\n", My_gid); printf ("effective Group id:%ld\n", My_egid):if(my_info) {printf ("My Login name:%s\n",my_info->;p w_name); printf ("My Password:%s\n",my_info->;p w_passwd); printf ("My User ID:%ld\n",my_info->;p W_uid); printf ("My Group ID:%ld\n",my_info->;p W_gid); printf ("My Real name:%s\n",my_info->;p W_gecos); printf ("My Home Dir:%s\n", my_info->;p W_dir); printf ("My Work shell:%s\n", my_info->;p W_shell); } } 3. The creation of a process creates a system call to a process that is simple. We just call the fork function. #include<unistd.h>; pid_t fork (); When a process calls fork, a child process is created. This child process differs from the parent process in that it has only his process ID and the parent process ID, and the others are the same. Just like the process clone (clone) itself. Of course Create Two identical processes are meaningless. In order to distinguish between parent and child processes, we must keep track of the return value of the fork. When the fork fails (out of memory or the maximum number of processes the user has reached) fork returns-1, otherwise the return value of f ork is important. Returns the ID of the child process for the parent process fork, and returns 0 for the fork child process. We distinguish the parent process by the return value. Why do I have to create a child process??As we said earlier, Linux is a multi-user operating system, at the same time there will be a lot of users competing for the resources of the system. Sometimes processes create child processes to compete for resources in order to complete tasks earlier. Once a child process is created, the parent-child process proceeds together from the fork, The resources of competing systems. Sometimes we want the child process to continue, and the parent process blocks until the child process finishes the task. We can call wait or waitpid system call at this time. #include<sys/types.h>; #include<sys/wait.h>; pid_t Wait (int*Stat_loc); pid_t waitpid (pid_t pid,int*stat_loc,intoptions); The wait system call causes the parent process to block until either a child process ends or the parent process receives a signal. If no parent process has no child process or his child process has ended, wait returns immediately. When successful (because a child process ends) wait returns the ID of the child process, otherwise returns-1, and set the global variable Errno.stat_loc is the exit state of the child process. The child process calls Exit,_exit or returns to set this value. To get this value, Linux defines several macros to test the return value. Wifexited: Determining the child process exit value is a non-0 Wexitstatus: Determines the exit value of the child process (not 0 when the child process exits). Wifsignaled: The child process exits because there is no received signal. Wtermsig: A signal number that is not obtained by the child process (meaning when wifsignaled is true). Waitpid waits for the specified child process to return until the child process returns. If the PID is positive, wait for the specified process (PID). If 0 waits for any one group ID and the caller's group ID is the same as the process. For-1 is equivalent to the wait call. Less than-1 o'clock wait for any one group ID equal to the PID absolute value of the process. Stat_loc and wait are the same. Options can determine the state of the parent process. You can take two values Wnohang: The parent process returns immediately when no child process exists. Wuntache D: Waitpid returns when the child process ends, but the exit status of the child process is not available. After the parent process creates the child process, the child process generally executes a different program. In order to invoke the System program, we can invoke the Exec family call using the system call. The Exec family call has 5 functions. #include<unistd.h>; intEXECL (Const Char*path,Const Char*arg,...); intEXECLP (Const Char*file,Const Char*arg,...); intExecle (Const Char*path,Const Char*arg,...); intExecvConst Char*path,Char*Constargv[]); intEXECVP (Const Char*file,Char*Constargv[]): The exec family call can execute a given program. For a detailed explanation of the call to the Exec family, refer to the System manual (man exec L). Let's learn an example. Note that when compiling-LM to connect a library of mathematical functions. #include<unistd.h>; #include<sys/types.h>; #include<sys/wait.h>; #include<stdio.h>; #include<errno.h>; #include<math.h>; voidMainvoid) {pid_t child;intstatus; printf ("This would demostrate how to get child status\n"); if((Child=fork ()) ==-1) {printf ("Fork Error:%s\n", Strerror (errno)); Exit (1); } Else if(child==0) { inti; printf ("I am the child:%ld\n", Getpid ()); for(i=0;i<1000000; i++) sin (i); I=5; printf ("I exit with%d\n", i); Exit (i); } while(((Child=wait (&status)) ==-1) & (errno==eintr)); if(child==-1) printf ("Wait error:%s\n", Strerror (errno)); Else if(!status) printf ("Child %ld terminated normally return status is zero\n", child); Else if(wifexited (status)) printf ("Child %ld terminated normally return status is%d\n", Child,wexitstatus (status)); Else if(wifsignaled (status)) printf ("Child %ld terminated due to signal%d Znot caught\n", Child,wtermsig (status)); The Strerror function returns a string that specifies the error number of the error message. 4. Daemon creation If you write programs in the DOS era, you probably know how much code we write in DOS in order to write a program that resides in memory. Conversely, if you write a"resident Memory"the program is easy. We can do it with just a few lines of code. In fact, because Linux is a multitasking operating system, we just don't write code and we can put a program in the background to do it. We just need to add the following command.&The symbol Shell will put our program in the background to run. Here we"Development"a program that checks the mail in the background. This program goes back to check our mailbox each time it is specified, and if we find that we have an email, we will keep the alarm (through the small speaker on the chassis to make the sound). There is an enhanced version of this function behind the idea of creating a background process: The parent process first creates a child process. Then the child process kills the parent process (isn't it ruthless?). Signal processing all work by child processes. #include<unistd.h>; #include<sys/types.h>; #include<sys/stat.h>; #include<stdio.h>; #include<errno.h>; #include<fcntl.h>; #include<signal.h>; /*The default email address for Linux is the/var/spool/mail/user's login name*/ #defineMAIL "/var/spool/mail/hoyt"/*Sleep 10 seconds*/ #defineSleep_time 10Main (void) {pid_t child;if((Child=fork ()) ==-1) {printf ("Fork error:%s\n", Strerror (errno)); Exit (1); } Else if(child>;0) while(1); if(Kill (Getppid (), SIGTERM) ==-1) {printf ("Kill Parent error:%s\n", Strerror (errno)); Exit (1); } { intMAILFD; while(1) { if((Mailfd=open (mail,o_rdonly))!=-1) {fprintf (stderr,"%s","\007"); Close (MAILFD); } sleep (Sleep_time); You can create your mailbox file under the default path, and then test the program. Of course, there are a lot of things to be improved about this program. We'll improve on this little program later on, and before you see my improvement, you can try to change it yourself. Be nice. For example, let the user specify the path of the mail phase and sleep time, and so on. Believe that you can do it. Go ahead, brave explorers. Okay, let's get to the process section. The process is a very important concept, and many programs use child processes. Creating a child process is a basic requirement for every programmer!
2) Getting Started with Linux programming--Process Introduction