orphan process with zombie process
Orphan process:
If the parent process exits first and the child process does not exit then the parent process of the child process becomes the init process. (Note: Any process must have a parent process)
Generate orphan process int main (int argc, char *argv[]) { pid_t pid = fork (); if (PID < 0) err_exit ("fork Error"); else if (PID > 0) exit (0); else { sleep (ten); cout << "Child, Ppid =" << getppid () << Endl; } Exit (0);}
Zombie Process:
If the child process exits first and the parent process does not exit, the child process must wait until the parent process captures the exit state of the child process to really end, otherwise the child process becomes a zombie process.
Build Zombie process int main (int argc, char *argv[]) { pid_t pid = fork (); if (PID < 0) err_exit ("fork Error"); else if (PID = = 0) exit (0); else { sleep (); } Exit (0);}
Attach -Query parent-child process status
Ps-le | grep Main
Avoid zombie processes
signal (SIGCHLD, sig_ign);
Example: avoid the zombie process int main (int argc, char *argv[]) { signal (SIGCHLD, sig_ign); pid_t pid = fork (); if (PID < 0) err_exit ("fork Error"); else if (PID = = 0) exit (0); else { sleep (); } Exit (0);}
file Sharing
All file descriptors of the parent process are copied to the child process, as if the DUP function was called, and the parent and child processes share a single file table entry for each of the same open file descriptors (hence, the parent-child process shares the same file offset);
According to: Understand the following program and the demo int main (int argc, char *argv[]) { signal (SIGCHLD, sig_ign); int fd = open ("Test.txt", o_wronly| O_creat| O_trunc, 0666); if (fd = =-1) err_exit ("File open Error"); cout << "We Don ' t flash memory\n"; Char Buf[bufsiz]; Bzero (buf, sizeof (BUF)); pid_t pid = fork (); if (PID < 0) err_exit ("fork Error"); else if (PID > 0) { strcpy (buf, "Parent ..."); Write (FD, buf, strlen (BUF)); Close (FD); cout << "fd =" << fd << Endl; Exit (0); } else if (PID = = 0) { strcpy (buf, "Child ..."); Write (FD, buf, strlen (BUF)); Close (FD); cout << "fd =" << fd << Endl; Exit (0);} }
Fork VS Vfork
The fork in Unix/linux has not been implemented before copy on write (copy-on-write) technology. UNIX designers are concerned about the waste of address space caused by exec immediately after fork, so the vfork system call is introduced. Where the Vfork child process shares data segments with the parent process, does not actually replicate the parent process memory, so executing the EXEC series functions after vfork does not result in a wasted address space and useless space-copy time. And even if the fork implements copy on write, Efficiency is not vfork high.
However, Vfork has a restriction that the child process must immediately execute the _exit or EXEC series functions . Therefore, we do not recommend the use of vfork, because almost every vfork implementation, there are more or less a certain problem (you can try to vfork after the child process is not executed _exit, and do not execute the EXEC function).
The difference between fork and vfork
The 1.fork child process copies the data segment of the parent process (but now provides a write-time replication technique that copies a copy of the memory only if the child process really needs to write memory), so the parent process/ Changes made to global variables in a child process do not affect the data content of the child process/parent process .
The Vfork child process shares the data segment with the parent process, so the parent-child process updates the data synchronously;
2.fork the execution order of the parent and child processes is unknown, depending on the scheduling algorithm of the operating system
Vfork: The child process runs first and then runs after the parent process ;
Example 1:vfork error condition//on the Linux 2.6 kernel will continue to execute, will not exit//and on the Linux 3.13 kernel, it will throw the core Dumpint main () {int inumber = 0; pid_t pid = Vfork (); if (PID = =-1) {perror ("fork"); return-1; } else if (PID > 0) {cout << "in the Parent program ..." << Endl; cout << "inumber =" << inumber << Endl; cout << "pid =" << static_cast<int> (Getpid ()); cout << "\ t ppid =" << static_cast<int> (Getppid ()) << Endl; _exit (0); } else if (PID = = 0) {inumber + +; cout << "in ..." << Endl; cout << "inumber =" << inumber << Endl; cout << "pid =" << static_cast<int> (Getpid ()); cout << "\ t ppid =" << static_cast<int> (Getppid ()) << Endl; _exit (0); } return 0;}
Example 2: case where the parent process/child process modifies global data int main () { int inumber = ten; cout << "before vfork, pid =" << getpid () << Endl; Compare fork () pid_t pid = vfork (); if (PID = =-1) err_exit ("fork"); else if (PID > 0) { sleep (4); cout << "Parent, Inumber:" << inumber << Endl; } else if (PID = = 0) { + + Inumber; cout << "Child, Inumber =" << inumber << Endl; _exit (0); } return 0;}
//Example 3: Executes the Hello program under the current directory with vfork int main () {int inumber = 0; pid_t pid = Vfork (); if (PID = =-1) {perror ("fork"); return-1; } else if (PID > 0) {cout << "in the Parent program ..." << Endl; cout << "inumber =" << inumber << Endl; cout << "pid =" << static_cast<int> (Getpid ()); cout << "\ t ppid =" << static_cast<int> (Getppid ()) << Endl; } else if (PID = = 0) {inumber + +; cout << "in ..." << Endl; cout << "inumber =" << inumber << Endl; cout << "pid =" << static_cast<int> (Getpid ()); cout << "\ t ppid =" << static_cast<int> (Getppid ()) << endl;//start up your own program Execve ("./hello", Null,null); _exit (0); } return 0;}
Test 4, execute the system command with vfork int main () {int inumber = 0; pid_t pid = Vfork (); if (PID = =-1) {perror ("fork"); return-1; } else if (PID > 0) {cout << "in the Parent program ..." << Endl; cout << "inumber =" << inumber << Endl; cout << "pid =" << static_cast<int> (Getpid ()); cout << "\ t ppid =" << static_cast<int> (Getppid ()) << Endl; } else if (PID = = 0) {inumber + +; cout << "in ..." << Endl; cout << "inumber =" << inumber << Endl; cout << "pid =" << static_cast<int> (Getpid ()); cout << "\ t ppid =" << static_cast<int> (Getppid ()) << endl;//start up the LS command, note: Due to the strict type conversion mechanism of C + +, Required before string (char*) char *const args[] = {(char *) "/bin/ls", (char *) "-L", NULL}; int res = EXECVE ("/bin/ls", args,null); if (res = =-1) { Perror ("Execve"); _exit (1); } _exit (0); } return 0;}
Linux process Practice (2)--zombie process and file sharing