IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> linux C语言wait()、waitpid()、waitid()函数(SIGCHLD、SA_NOCLDWAIT、WNOHANG、SIGCONT) -> 正文阅读

[系统运维]linux C语言wait()、waitpid()、waitid()函数(SIGCHLD、SA_NOCLDWAIT、WNOHANG、SIGCONT)

文章目录

man 2 文档

WAIT(2)                                                              Linux Programmer's Manual                                                             WAIT(2)

NAME
       wait, waitpid, waitid - wait for process to change state	//等待进程改变状态

SYNOPSIS
       #include <sys/types.h>
       #include <sys/wait.h>

       pid_t wait(int *status);

       pid_t waitpid(pid_t pid, int *status, int options);

       int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
                       /* This is the glibc and POSIX interface; see
                          NOTES for information on the raw system call. */

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       waitid():
           _SVID_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
           || /* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200809L

DESCRIPTION
       All  of  these  system  calls  are used to wait for state changes in a child of the calling process, and obtain information about the child whose state has
       changed.  A state change is considered to be: the child terminated; the child was stopped by a signal; or the child was resumed by a signal.  In  the  case
       of  a terminated child, performing a wait allows the system to release the resources associated with the child; if a wait is not performed, then the termi‐
       nated child remains in a "zombie" state (see NOTES below).

		//所有这些系统调用都用于等待调用进程的子进程的状态变化,并获取有关其状态已更改的子进程的信息。 
		//状态变化被认为是:孩子终止; 孩子被信号拦住; 或者孩子被一个信号恢复了。 
		//在孩子被终止的情况下,执行wait允许系统释放与孩子关联的资源; 
		//如果未执行wait,则被终止的子进程将保持“僵尸”状态(参见下面的注释)。

       If a child has already changed state, then these calls return immediately.  Otherwise, they block until either a child changes state or  a  signal  handler
       interrupts the call (assuming that system calls are not automatically restarted using the SA_RESTART flag of sigaction(2)).  In the remainder of this page,
       a child whose state has changed and which has not yet been waited upon by one of these system calls is termed waitable.

		//如果一个孩子已经改变了状态,那么这些调用会立即返回。 
		//否则,它们会阻塞,直到子进程改变状态或信号处理程序中断调用(假设系统调用不会使用 sigaction(2) 的 SA_RESTART 标志自动重新启动)。 
		//在本页的其余部分中,状态已更改,且尚未被这些系统调用之一wait的孩子,称为可等待的(waitable)。

   wait() and waitpid()
       The wait() system call suspends execution of the calling process until one of its children terminates.  The call wait(&status) is equivalent to:
       //wait() 系统调用暂停调用进程的执行,直到其子进程之一终止。 调用 wait(&status) 等价于:

           waitpid(-1, &status, 0);

       The waitpid() system call suspends execution of the calling process until a child specified by pid argument has changed state.  By default, waitpid() waits
       only for terminated children, but this behavior is modifiable via the options argument, as described below.
       //waitpid() 系统调用暂停调用进程的执行,直到 pid 参数指定的子进程改变状态。 
       //默认情况下,waitpid() 仅等待被终止的子进程,但此行为可通过 options 参数进行修改,如下所述。

       The value of pid can be:
       //pid 的值可以是:

       < -1   meaning wait for any child process whose process group ID is equal to the absolute value of pid.
       //小于-1意味着等待任何进程组 ID 等于 pid 绝对值的子进程。

       -1     meaning wait for any child process.
       //等于-1意味着等待任何子进程。

       0      meaning wait for any child process whose process group ID is equal to that of the calling process.
       //等于0意味着等待其进程组 ID 与调用进程相同的任何子进程。

       > 0    meaning wait for the child whose process ID is equal to the value of pid.
       //大于0意味着等待进程 ID 等于 pid 值的子进程。

       The value of options is an OR of zero or more of the following constants:
       //options 的值是以下常量中的零个或多个的 OR:(OR是什么?)

       WNOHANG     return immediately if no child has exited.
       				//如果没有孩子退出,则立即返回。

       WUNTRACED   also  return  if  a  child  has stopped (but not traced via ptrace(2)).  Status for traced children which have stopped is provided even if this
                   option is not specified.
                   //如果孩子已经停止(但没有通过 ptrace(2) 跟踪),也会返回。 
                   //即使未指定此选项,也会提供已停止的跟踪子项的状态。

       WCONTINUED (since Linux 2.6.10)
                   also return if a stopped child has been resumed by delivery of SIGCONT.
                   //如果通过 SIGCONT 的传递恢复了停止的孩子,也返回。

       (For Linux-only options, see below.)

       If status is not NULL, wait() and waitpid() store status information in the int to which it points.  This integer  can  be  inspected  with  the  following
       macros (which take the integer itself as an argument, not a pointer to it, as is done in wait() and waitpid()!):
       //如果 status 不为 NULL,wait() 和 waitpid() 将状态信息存储在它指向的 int 中。 
       //可以使用以下宏检查此整数(将整数本身作为参数,而不是指向它的指针,就像在 wait() 和 waitpid() 中所做的那样!):

       WIFEXITED(status)
              returns true if the child terminated normally, that is, by calling exit(3) or _exit(2), or by returning from main().
              //如果子进程正常终止,即调用 exit(3) 或 _exit(2),或者从 main() 返回,则返回 true。

       WEXITSTATUS(status)
              returns  the  exit  status of the child.  This consists of the least significant 8 bits of the status argument that the child specified in a call to
              exit(3) or _exit(2) or as the argument for a return statement in main().  This macro should be employed only if WIFEXITED returned true.
              //返回孩子的退出状态。 这由状态参数的最低有效 8 位组成,子进程在调用 exit(3) 或 _exit(2) 时指定或作为 main() 中的 return 语句的参数。 
              //仅当 WIFEXITED 返回 true 时才应使用此宏。

       WIFSIGNALED(status)
              returns true if the child process was terminated by a signal.
              //如果子进程被信号终止,则返回 true。

       WTERMSIG(status)
              returns the number of the signal that caused the child process to terminate.  This macro should be employed only if WIFSIGNALED returned true.
              //返回导致子进程终止的信号的编号。 仅当 WIFSIGNALED 返回 true 时才应使用此宏。

       WCOREDUMP(status)
              returns true if the child produced a core dump.  This macro should be employed only if WIFSIGNALED returned true.  This macro is  not  specified  in
              POSIX.1-2001 and is not available on some UNIX implementations (e.g., AIX, SunOS).  Only use this enclosed in #ifdef WCOREDUMP ... #endif.
              //如果孩子产生了核心转储,则返回 true。 
              //仅当 WIFSIGNALED 返回 true 时才应使用此宏。 
              //此宏未在 POSIX.1-2001 中指定,并且在某些 UNIX 实现(例如 AIX、SunOS)上不可用。 
              //仅使用 #ifdef WCOREDUMP ... #endif 中包含的此项。

       WIFSTOPPED(status)
              returns  true if the child process was stopped by delivery of a signal; this is possible only if the call was done using WUNTRACED or when the child
              is being traced (see ptrace(2)).
              //如果子进程因传递信号而停止,则返回 true; 
              //仅当使用 WUNTRACED 完成调用或正在跟踪孩子时(请参阅 ptrace(2)),这才有可能。

       WSTOPSIG(status)
              returns the number of the signal which caused the child to stop.  This macro should be employed only if WIFSTOPPED returned true.
              //返回导致孩子停止的信号的编号。 仅当 WIFSTOPPED 返回 true 时才应使用此宏。

       WIFCONTINUED(status)
              (since Linux 2.6.10) returns true if the child process was resumed by delivery of SIGCONT.
              //(从 Linux 2.6.10 开始)如果子进程通过传递 SIGCONT 恢复,则返回 true。(SIGCONT是进程继续的意思,继续曾被停止的进程)

   waitid()
       The waitid() system call (available since Linux 2.6.9) provides more precise control over which child state changes to wait for.
       //waitid() 系统调用(自 Linux 2.6.9 起可用)提供更精确的控制来控制要等待的子进程状态更改。

       The idtype and id arguments select the child(ren) to wait for, as follows:
       //idtype 和 id 参数选择要等待的 child(ren),如下所示:

       idtype == P_PID
              Wait for the child whose process ID matches id.

       idtype == P_PGID
              Wait for any child whose process group ID matches id.

       idtype == P_ALL
              Wait for any child; id is ignored.

       The child state changes to wait for are specified by ORing one or more of the following flags in options:

       WEXITED     Wait for children that have terminated.

       WSTOPPED    Wait for children that have been stopped by delivery of a signal.

       WCONTINUED  Wait for (previously stopped) children that have been resumed by delivery of SIGCONT.

       The following flags may additionally be ORed in options:

       WNOHANG     As for waitpid().

       WNOWAIT     Leave the child in a waitable state; a later wait call can be used to again retrieve the child status information.

       Upon successful return, waitid() fills in the following fields of the siginfo_t structure pointed to by infop:

       si_pid      The process ID of the child.

       si_uid      The real user ID of the child.  (This field is not set on most other implementations.)

       si_signo    Always set to SIGCHLD.

       si_status   Either the exit status of the child, as given to _exit(2) (or exit(3)), or the signal that caused the child to terminate,  stop,  or  continue.
                   The si_code field can be used to determine how to interpret this field.

       si_code     Set  to  one of: CLD_EXITED (child called _exit(2)); CLD_KILLED (child killed by signal); CLD_DUMPED (child killed by signal, and dumped core);
                   CLD_STOPPED (child stopped by signal); CLD_TRAPPED (traced child has trapped); or CLD_CONTINUED (child continued by SIGCONT).

       If WNOHANG was specified in options and there were no children in a waitable state, then waitid() returns 0 immediately and  the  state  of  the  siginfo_t
       structure  pointed  to by infop is unspecified.  To distinguish this case from that where a child was in a waitable state, zero out the si_pid field before
       the call and check for a nonzero value in this field after the call returns.

RETURN VALUE
       wait(): on success, returns the process ID of the terminated child; on error, -1 is returned.
       //成功时,返回终止子进程的进程 ID; 出错时,返回 -1。

       waitpid(): on success, returns the process ID of the child whose state has changed; if WNOHANG was specified and one or more child(ren)  specified  by  pid
       exist, but have not yet changed state, then 0 is returned.  On error, -1 is returned.
       //成功时,返回状态已更改的子进程 ID; 
       //如果指定了 WNOHANG 并且存在一个或多个由 pid 指定的子进程,但尚未更改状态,则返回 0。 
       //出错时,返回 -1。

       waitid(): returns 0 on success or if WNOHANG was specified and no child(ren) specified by id has yet changed state; on error, -1 is returned.
       //成功时返回 0,或者如果指定了 WNOHANG 并且 id 指定的子进程尚未更改状态; 
       //出错时,返回 -1。

       Each of these calls sets errno to an appropriate value in the case of an error.
       //在发生错误的情况下,这些调用中的每一个都将 errno 设置为适当的值。

ERRORS
       ECHILD (for wait()) The calling process does not have any unwaited-for children.
       //ECHILD (for wait()) 调用进程没有任何未等待的子进程。

       ECHILD (for  waitpid()  or  waitid())  The process specified by pid (waitpid()) or idtype and id (waitid()) does not exist or is not a child of the calling
              process.  (This can happen for one's own child if the action for SIGCHLD is set to SIG_IGN.  See also the Linux Notes section about threads.)
       //ECHILD (for waitpid() or waitid()) pid(waitpid())或idtype和id(waitid())指定的进程不存在或者不是调用进程的子进程。 (如果 SIGCHLD 的操作设置为 SIG_IGN,这可能发生在自己的孩子身上。另请参阅有关线程的 Linux 注释部分。)

       EINTR  WNOHANG was not set and an unblocked signal or a SIGCHLD was caught; see signal(7).
       //未设置 EINTR WNOHANG 并且捕获了未阻塞的信号或 SIGCHLD; 见信号(7)。

       EINVAL The options argument was invalid.
       //EINVAL 选项参数无效。

CONFORMING TO
       SVr4, 4.3BSD, POSIX.1-2001.

NOTES
       A child that terminates, but has not been waited for becomes a "zombie".  The kernel maintains a minimal set of information about the zombie process  (PID,
       termination  status,  resource usage information) in order to allow the parent to later perform a wait to obtain information about the child.  As long as a
       zombie is not removed from the system via a wait, it will consume a slot in the kernel process table, and if this table fills, it will not be  possible  to
       create  further processes.  If a parent process terminates, then its "zombie" children (if any) are adopted by init(1), which automatically performs a wait
       to remove the zombies.
       //终止但没有被waited的孩子成为“僵尸”。 
       //内核维护有关僵尸进程的最小信息集(PID、终止状态、资源使用信息),以便允许父进程稍后执行等待以获取有关子进程的信息。 
       //只要僵尸没有通过等待从系统中移除,它就会消耗内核进程表中的一个槽(slot),如果这个表填满,就不能再创建更多的进程。 
       //如果父进程终止,那么它的“僵尸”子进程(如果有)会被 init(1) 采用,它会自动执行等待以移除僵尸进程。

       POSIX.1-2001 specifies that if the disposition of SIGCHLD is set to SIG_IGN or the SA_NOCLDWAIT flag is set for SIGCHLD (see sigaction(2)),  then  children
       that  terminate  do  not  become  zombies  and a call to wait() or waitpid() will block until all children have terminated, and then fail with errno set to
       ECHILD.  (The original POSIX standard left the behavior of setting SIGCHLD to SIG_IGN unspecified.  Note  that  even  though  the  default  disposition  of
       SIGCHLD is "ignore", explicitly setting the disposition to SIG_IGN results in different treatment of zombie process children.)
       //POSIX.1-2001 指定如果 SIGCHLD 的处置设置为 SIG_IGN 或为 SIGCHLD 设置了 SA_NOCLDWAIT 标志(请参阅 sigaction(2)),则终止的子进程不会变成僵尸并且调用 wait() 或 waitpid() 将阻塞,直到所有子节点都终止,然后失败,errno 设置为 ECHILD。 
       //(原始 POSIX 标准未指定将 SIGCHLD 设置为 SIG_IGN 的行为。请注意,即使 SIGCHLD 的默认处置是“忽略”,显式将处置设置为 SIG_IGN 会导致对僵尸进程子进程的不同处理。)

       Linux  2.6  conforms  to  the  POSIX requirements.  However, Linux 2.4 (and earlier) does not: if a wait() or waitpid() call is made while SIGCHLD is being
       ignored, the call behaves just as though SIGCHLD were not being ignored, that is, the call blocks until the next child  terminates  and  then  returns  the
       process ID and status of that child.
       //Linux 2.6 符合 POSIX 要求。 
       //但是,Linux 2.4(和更早版本)没有:如果在忽略 SIGCHLD 时调用了 wait() 或 waitpid(),则调用的行为就像 SIGCHLD 没有被忽略一样,也就是说,调用会阻塞到下一个 child 终止,然后返回该 child 的进程 ID 和状态。

   Linux notes
       In the Linux kernel, a kernel-scheduled thread is not a distinct construct from a process.  Instead, a thread is simply a process that is created using the
       Linux-unique clone(2) system call; other routines such as the portable pthread_create(3) call are implemented using clone(2).  Before Linux 2.4,  a  thread
       was just a special case of a process, and as a consequence one thread could not wait on the children of another thread, even when the latter belongs to the
       same thread group.  However, POSIX prescribes such functionality, and since Linux 2.4 a thread can, and by default will, wait on children of other  threads
       in the same thread group.
      	//在 Linux 内核中,内核调度的线程不是与进程不同的构造。 
      	//相反,线程只是一个使用 Linux 独有的 clone(2) 系统调用创建的进程; 
      	//其他例程,例如可移植的 pthread_create(3) 调用是使用 clone(2) 实现的。 在 Linux 2.4 之前,线程只是进程的一种特殊情况,因此一个线程不能等待另一个线程的子线程,即使后者属于同一个线程组。 
      	//但是,POSIX 规定了这样的功能,并且从 Linux 2.4 开始,线程可以并且默认情况下会等待同一线程组中其他线程的子线程。

       The following Linux-specific options are for use with children created using clone(2); they cannot be used with waitid():
       //以下特定于 Linux 的选项适用于使用 clone(2) 创建的子代; 它们不能与 waitid() 一起使用:

       __WCLONE
              Wait for "clone" children only.  If omitted, then wait for "non-clone" children only.  (A "clone" child is one which delivers no signal, or a signal
              other than SIGCHLD to its parent upon termination.)  This option is ignored if __WALL is also specified.

       __WALL (since Linux 2.4)
              Wait for all children, regardless of type ("clone" or "non-clone").

       __WNOTHREAD (since Linux 2.4)
              Do not wait for children of other threads in the same thread group.  This was the default before Linux 2.4.

   C library/kernel differences
       wait() is actually a library function that (in glibc) is implemented as a call to wait4(2).
       //wait() 实际上是一个库函数,(在 glibc 中)被实现为对 wait4(2) 的调用。

       Within glibc, waitpid() is a wrapper function that invokes wait(2).
       //在 glibc 中,waitpid() 是一个调用 wait(2) 的包装函数。

       The raw waitid() system call takes a fifth argument, of type struct rusage *.  If this argument is non-NULL, then it  is  used  to  return  resource  usage
       information about the child, in the same manner as wait4(2).  See getrusage(2) for details.
       //原始的 waitid() 系统调用采用 struct rusage * 类型的第五个参数。 
       //如果此参数为非 NULL,则它用于返回有关子节点的资源使用信息,方式与 wait4(2) 相同。 
       //有关详细信息,请参阅 getrusage(2)。

BUGS
       According  to  POSIX.1-2008,  an application calling waitid() must ensure that infop points to a siginfo_t structure (i.e., that it is a non-null pointer).
       On Linux, if infop is NULL, waitid() succeeds, and returns the process ID of the waited-for child.  Applications should avoid relying on this inconsistent,
       nonstandard, and unnecessary feature.
       //根据 POSIX.1-2008,调用 waitid() 的应用程序必须确保 infop 指向 siginfo_t 结构(即,它是一个非空指针)。 
       //在 Linux 上,如果 infop 为 NULL,则 waitid() 成功,并返回等待子进程的进程 ID。 应用程序应避免依赖这种不一致、非标准和不必要的特性。

EXAMPLE
       The  following program demonstrates the use of fork(2) and waitpid().  The program creates a child process.  If no command-line argument is supplied to the
       program, then the child suspends its execution using pause(2), to allow the user to send signals to the child.  Otherwise, if a  command-line  argument  is
       supplied,  then  the  child  exits immediately, using the integer supplied on the command line as the exit status.  The parent process executes a loop that
       monitors the child using waitpid(), and uses the W*() macros described above to analyze the wait status value.
       //下面的程序演示了 fork(2) 和 waitpid() 的使用。 
       //该程序创建一个子进程。 如果没有向程序提供命令行参数,则子进程使用 pause(2) 暂停其执行,以允许用户向子进程发送信号。 
       //否则,如果提供了命令行参数,则子进程立即退出,使用命令行上提供的整数作为退出状态。 父进程执行一个循环,使用waitpid() 监视子进程,并使用上述W*() 宏来分析等待状态值。

       The following shell session demonstrates the use of the program:
       //以下 shell 会话演示了该程序的使用:(意思是进程被STOP后还能被continue继续运行?)

           $ ./a.out &
           Child PID is 32360
           [1] 32359
           $ kill -STOP 32360
           stopped by signal 19
           $ kill -CONT 32360
           continued
           $ kill -TERM 32360
           killed by signal 15
           [1]+  Done                    ./a.out
           $

   Program source

       #include <sys/wait.h>
       #include <stdlib.h>
       #include <unistd.h>
       #include <stdio.h>

       int
       main(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 */
               printf("Child PID is %ld\n", (long) getpid());
               if (argc == 1)
                   pause();                    /* Wait for signals */
               _exit(atoi(argv[1]));

           } else {                    /* Code executed by parent */
               do {
                   w = waitpid(cpid, &status, WUNTRACED | WCONTINUED);
                   if (w == -1) {
                       perror("waitpid");
                       exit(EXIT_FAILURE);
                   }
                   if (WIFEXITED(status)) {
                       printf("exited, status=%d\n", WEXITSTATUS(status));
                   } else if (WIFSIGNALED(status)) {
                       printf("killed by signal %d\n", WTERMSIG(status));
                   } else if (WIFSTOPPED(status)) {
                       printf("stopped by signal %d\n", WSTOPSIG(status));
                   } else if (WIFCONTINUED(status)) {
                       printf("continued\n");
                   }
               } while (!WIFEXITED(status) && !WIFSIGNALED(status));
               exit(EXIT_SUCCESS);
           }
       }

SEE ALSO
       _exit(2), clone(2), fork(2), kill(2), ptrace(2), sigaction(2), signal(2), wait4(2), pthread_create(3), credentials(7), signal(7)

COLOPHON
       This page is part of release 4.04 of the Linux man-pages project.  A description of the project, information about reporting bugs, and the  latest  version
       of this page, can be found at http://www.kernel.org/doc/man-pages/.

Linux                                                                       2015-07-23                                                                     WAIT(2)
 Manual page wait(2) line 244/285 (END) (press h for help or q to quit)

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-05-05 12:01:58  更:2022-05-05 12:04:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 18:41:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码