[C/C ++] multi-process: the parent process listens to the use of the sub-process status wait () and listens to the wait

Source: Internet
Author: User

[C/C ++] multi-process: the parent process listens to the use of the sub-process status wait () and listens to the wait

Article structure:

  • Wait capability Introduction
  • Wait () function description
  • DEMO code and Operation
Wait capability Introduction

In the previous article [C/C ++] multi-process: creating a sub-process fork (), we demonstrated the creation of a sub-process.

After a child process is created, the parent process can monitor the running status of the child process. The functions used are as follows:

   #include <sys/wait.h>   pid_t wait(int *status);   pid_t waitpid(pid_t pid, int *status, int options);

The preceding functions are used to wait for the callback of the sub-process status change and obtain the status change information. Possible status changes include: the sub-process stops running, the sub-process is paused by the semaphore, and the sub-process is resumed by the semaphore.

The parent process is executed.waitAfter the function, if the sub-process has changed its statuswaitThe function returns results immediately. OtherwisewaitThe function is blocked until the sub-process status changes.

Generally, if the sub-process has changed its status but has not been executed by the parent process or other system callbackswaitThe sub-process is called waitable ).

After the sub-process ends, the parent executeswaitA function can push the system to release resources related to sub-processes; otherwise, sub-processes will be maintained inBotnets.

Wait () function description

Functionwait(int * status)Yeswaitpid()Only when any sub-process stops running. Otherwise, the called process is blocked and paused.wait(int * status)Equivalent to the following code:

       waitpid(-1, &status, 0);

  waitpid()The call process will be blocked until the running status of any sub-process changes. Nextwaitpid()The three parameters are described as follows:

  • Pid

  pid < -1Take the absolute value of the pid. If the process group ID of any sub-process is equal to the absolute value, changes in the Process status of any sub-process in the group will triggerwaitpid().

  pid == -1The listening scope is extended to any sub-process.

  pid == 0The ID of the process group where the listener is restricted to sub-processes is equal to that of the parent process.

  pid > 0The ID of the specified sub-process.

  • Status

The value can beNULL. When notNULLIs used to store the information value that triggers the status change andexit(code)IncodeValue.

  wait.hThe header file defines several macros for parsing.statusCommon values include:

Macro Description
WIFEXITED (status)

WEXITSTATUS (status)
When a sub-process callsexit(code)Or_exit(code)Or runmain()Returnstrue.

WhenWIFEXITED(status)IstrueObtainexit(code)Or_exit(code)OfcodeValue.
WherecodeIt can only be 0 or positive. Negative numbers are not supported.
WIFSIGNALED (status)

WTERMSIG (status)
Returned when the child process is killed by a semaphoretrue.

WhenWIFSIGNALED(status)IstrueTo obtain the semaphore value.
WIFSTOPPED (status)

WSTOPSIG (status)
Returned when the sub-process is paused by the semaphoretrue.

WhenWIFSTOPPED(status)IstrueTo obtain the semaphore value.
  • Options

The value can be any value of the following constant or any constant and zeroORCalculate the value.

Constant Description
WNOHANG CallwaitSpecifiedpidIf the operation is still not completedwaitReturns 0 immediately.
WUNTRACED When the sub-process is pausedwaitReturnspid.
WCONTINUED
When the paused sub-process is restored by the semaphorewaitReturnspid.
Linux 2.6.10 and later. It does not take effect on Mac 0 s x 10.9.5.

  wait()The function returnspidValue. If an error occurs during execution,-1 is returned.
  waitpid()When a function is executed normally, it returns a process whose status changes.pidValue; if the function options containsWNOHANGConstantpidIf the sub-process has not exited and the Process status has not changed, return 0 directly. If the sub-process has exited, return the sub-process'spidOtherwise,-1 is returned when an error occurs.

DEMO code and Operation

Due to the two processes involved, log printing on the terminal command line may be messy, so the logs of the two processes are output to two files by redirecting the standard input/output stream, logs of the parent process are outputmain.txtSub-process logs are outputchild.txt. This involves redirecting standard input/output streams. For details, see [C/C ++] File Creation, opening, reading, writing, copying, closing, deleting, and other operations.

Involvedps,killYou can useman psAndman killSearch for details.

The following code will demonstratefork()After a sub-process passespsCommand to query the Process status andkillCommand to send a semaphore to the sub-process to change the process status; the parent process passeswaitListen to the sub-process status.

  wait.cThe source code is as follows:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
# Include <sys/wait. h> # include <errno. h> # include <stdlib. h> # include <string. h> # include <unistd. h> # include <stdio. h> # include <time. h> # ifndef CHILD_COUNT # define CHILD_COUNT 10000 # endifstatic void printTime () {time_t calendar_time = time (NULL); struct tm * tm_local = localtime (& calendar_time ); char str_f_t [50]; strftime (str_f_t, sizeof (str_f_t), "% G-% m-% d % H: % M: % S", tm_local ); printf ("% s", str_f_t);} int main/* 09 */(int argc, char * argv []) {pid_t cpid, w; int status; cpid = fork (); if (cpid =-1) {perror ("fork"); exit (EXIT_FAILURE);} if (cpid = 0) {/* Code executed by child */FILE * fChild = freopen ("/Users/sodino/workspace/xcode/Define/child.txt", "w", stdout ); printTime (); printf ("Child PID is % ld argc = % d \ n", (long) getpid (), argc); int count = 0; do {sleep (1); printTime (); printf ("sleep count = % d \ n", count); fflush (fChild); count ++; if (count> CHILD_COUNT) {break;} while (1); fflush (fChild); fclose (fChild); // The code value will be from the parent process's WEXITSTATUS () in macro definition, learn // _ exit (123); exit (123 );} else {FILE * fMain = freopen ("/Users/sodino/workspace/xcode/Define/main.txt", "w", stdout); // If the sub-process is still running, 0 is returned. if the sub-process has completed running, the sub-process pid w = waitpid (cpid, & status, WNOHANG) is returned; if (w = 0) {printTime (); printf ("Child PID = % d has not yet changed state \ n", cpid);} else {printTime (); printf ("Child PID = % d has been terminated. \ n ", cpid);} int ifExited, ifSignaled, ifStopped, ifContinued;/* Code executed by parent */do {// invalid on mac · WCONTINUED, from the perspective of the file, it only applies to thread w = waitpid (cpid, & status, WUNTRACED | WCONTINUED); // w = waitpid (cpid, & status, WUNTRACED ); if (w =-1) {printTime (); printf ("Parent w =-1, error = % s \ n", strerror (errno )); exit (EXIT_FAILURE);} if (w = 0) {printTime (); printf ("w = 0 ignore. continue. \ n "); continue;} ifExited = WIFEXITED (status); ifSignaled = WIFSIGNALED (status); ifStopped = WIFSTOPPED (status); ifContinued = WIFCONTINUED (status); printTime (); printf ("pid = % ld w = % d exitCode = % d status = % d ifExited = % d ifSignaled = % d ifStopped = % d ifContinued = % d \ n ", (long) getpid (), // w, status, WEXITSTATUS (w), ifExited, ifSignaled, ifStopped, ifContinued); w, status, _ WSTATUS (w), ifExited, ifSignaled, ifStopped, ifContinued); printTime (); if (ifExited) {printf ("PID = % ld exited, status = % d \ n", (long) w, WEXITSTATUS (status);} else if (ifSignaled) {printf ("PID = % ld killed by signal % d \ n", (long) w, WTERMSIG (status);} else if (ifStopped) {printf ("PID = % ld stopped by signal % d \ n", (long) w, WSTOPSIG (status);} else if (ifContinued) {printf ("PID = % ld continued \ n", (long) w);} fflush (fMain ); if (ifExited | ifSignaled) {printTime (); printf ("isExited = % d isSingaled = % d \ n", ifExited, ifSignaled); fflush (fMain ); break ;}} while (1); printTime (); printf ("Main PID % ld exit. \ n ", (long) getpid (); fclose (fMain); exit (EXIT_SUCCESS );}}

Gowait.cTo compile and run the following command:

Gcc wait. c // generate the executable file a. out./a. out // run the executable file

Useps -jCommand to view the process.fork()After the process is executed, there are two names in the Process List:a.out. For example:

We can see that the parent process of PID = 678 is PID = 677. The PGID of both processes is 677.

WatchingSTATColumn, both processes areS+, WhereSIndicates that the process is insleepingStatus because the parent process is inwaitIn addition to printing logs, sub-processes are running most of the time.sleep(); Another+Indicates that both processes are in the foreground of the current console.

Connect to usekill -SIGSTOP 678Command to send a pause signal to the sub-process, and thenps -jCheck the Process status and find that the sub-process 678 has beenS+ChangeT+Is in the STOP status.

On the other hand, Viewchild.txtThe file will no longer generate logs. Viewmain.txtFile. The log content is as follows:

  2015-04-16 22:53:15 Child PID=678 has not yet changed state  2015-04-16 23:11:48 pid=677 w=678 exitCode=4479 status=38 ifExited=0 ifSignaled=0 ifStopped=1 ifContinued=0   2015-04-16 23:11:48 PID=678 stopped by signal 17

First sentenceChild PID=678 has not yet changed stateYesparent Process Executionwaitpid:WNOHANGThe returned result indicates that the sub-process has not exited and is running. The second sentence is output.ifStopped=1Indicateswaitpid:WUNTRACEDThe system has monitored the semaphore sent by the sub-process to change the process status. Third sentencePID=678 stopped by signal 17Indicates that the signal value is 17. The following command may verify that the SIGSTOP signal value is 17:

  sodino:Define sodino$ kill -l SIGSTOP  17

Next, continue to usekill -SIGCONT 678Command to restore the sub-process running, see:

The sub-process resumes running from the stopped status. Viewchild.txtThe log returns the output again:

   ... ...   2015-04-16 23:11:46 sleep count=1110   2015-04-16 23:11:47 sleep count=1111   2015-04-16 23:23:20 sleep count=1112   2015-04-16 23:23:21 sleep count=1113   ... ...

Note that the Process status is stopped during the period from to, so no log output is available (you can write a blog during this period of time ..). Viewmain.txtNowaitpidI personally think this is a problem with the C version and runtime environment on my mac.

Finally, use the commandkill -SIGTERM 678You can findpsThe command cannot be found.a.outProcess.

Viewmain.txtWe can find thatwaitpidWith the return valueifSignaled=1Indicates that the sub-process has been semaphores15Killed. And finally quit.

 2015-04-16 23:31:00 pid=677 w=678 exitCode=15 status=38 ifExited=0 ifSignaled=1 ifStopped=0 ifContinued=0  2015-04-16 23:31:00 PID=678 killed by signal 15 2015-04-16 23:31:00 isExited=0   isSingaled=1 2015-04-16 23:31:00 Main PID 677  exit.

The above is what I want to talk about in this article. Next: multi-process: Zombie Process

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.