C语言中的wait系统调用详细指南

2021年3月12日14:27:46 发表评论 1,060 次浏览

先决条件: 货叉系统调用

对wait()的调用将阻止调用进程, 直到其子进程之一退出或接收到信号为止。子进程终止后, 父进程

继续

等待系统调用指令后执行。

子进程可能由于以下原因而终止:

  • 它调用exit();
  • 它从main返回(int)
  • 它从操作系统或其他进程接收信号, 其默认操作是终止。
C语言中的wait系统调用详细指南

C语言语法:

#include
#include

// take one argument status and returns 
// a process ID of dead children.
pid_t wait(int *stat_loc);

如果任何进程具有多个子进程, 则在调用wait()之后, 如果没有子进程终止, 则父进程必须处于等待状态。

如果只有一个子进程终止, 则返回一个wait()返回终止的子进程的进程ID。

如果终止了多个子进程, 则比wait()收获任何子进程

随便的孩子

并返回该子进程的进程ID。

当wait()返回时, 它们还定义

退出状态

(告诉我们, 一个进程为什么终止), 如果没有, 则通过指针

null

.

如果任何进程没有子进程, 则wait()立即返回" -1"。

注意:"由于环境问题, 此代码无法在简单的IDE中运行, 因此请使用终端来运行代码"

例子:

// C program to demonstrate working of wait()
#include<stdio.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<unistd.h>
  
int main()
{
     pid_t cpid;
     if (fork()== 0)
         exit (0);           /* terminate child */
     else
         cpid = wait(NULL); /* reaping parent */
     printf ( "Parent pid = %d\n" , getpid());
     printf ( "Child pid = %d\n" , cpid);
  
     return 0;
}

输出如下:

Parent pid = 12345678 
Child pid = 89546848
// C program to demonstrate working of wait()
#include<stdio.h>
#include<sys/wait.h>
#include<unistd.h>
  
int main()
{
     if (fork()== 0)
         printf ( "HC: hello from child\n" );
     else
     {
         printf ( "HP: hello from parent\n" );
         wait(NULL);
         printf ( "CT: child has terminated\n" );
     }
  
     printf ( "Bye\n" );
     return 0;
}

输出:取决于环境

HC: hello from child
Bye
HP: hello from parent
CT: child has terminated
     (or)
HP: hello from parent
HC: hello from child
CT: child has terminated    // this sentence does 
                            // not print before HC 
                            // because of wait.
Bye

子状态信息:

通过等待报告的关于孩子的状态信息不仅是孩子的退出状态, 还包括

  • 正常/异常终止
  • 终止原因
  • 退出状态

要查找有关状态的信息, 我们使用

WIF

…。宏

1.

WIFEXITED(状态)

:孩子正常退出

WEXITSTATUS(状态)

:孩子退出时返回代码

2.

WIFSIGNALED(状态)

:孩子退出, 因为未捕获到信号

WTERMSIG(状态)

:给出终止信号的编号

3.

WIFSTOPPED(状态)

:孩子停止了

WSTOPSIG(状态)

:给出停止信号的编号

/*if we want to prints information about a signal */
void psignal(unsigned sig, const char *s);

例子:

检查以下程序的输出。

// C program to demonstrate working of status
// from wait.
#include<stdio.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<unistd.h>
  
void waitexample()
{
     int stat;
  
     // This status 1 is reported by WEXITSTATUS
     if (fork() == 0)
         exit (1);
     else
         wait(&stat);
     if (WIFEXITED(stat))
         printf ( "Exit status: %d\n" , WEXITSTATUS(stat));
     else if (WIFSIGNALED(stat))
         psignal(WTERMSIG(stat), "Exit signal" );
}
  
// Driver code
int main()
{
     waitexample();
     return 0;
}

输出如下:

Exit status: 1

我们知道如果终止了多个子进程, 那么wait()会获得任意子进程, 但是如果我们想获得任何特定的子进程, 我们将使用waitpid()功能。

C语言语法:pid_t waitpid(child_pid, &status, 选项);

选项参数

  • 如果为0表示没有选项, 则父级不必等待终止子级。
  • If万航表示如果子项未终止则父项不等待, 只需检查并返回waitpid()。(不阻止父级进程)
  • 如果child_pid是-1那么意味着随便的孩子, 这里的waitpid()工作与wait()工作相同。

waitpid()的返回值

  • 孩子的pid(如果孩子退出了)
  • 0, 如果使用WNOHANG并且未退出孩子
// C program to demonstrate waitpid()
#include<stdio.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<unistd.h>
  
void waitexample()
{
     int i, stat;
     pid_t pid[5];
     for (i=0; i<5; i++)
     {
         if ((pid[i] = fork()) == 0)
         {
             sleep(1);
             exit (100 + i);
         }
     }
  
     // Using waitpid() and printing exit status
     // of children.
     for (i=0; i<5; i++)
     {
         pid_t cpid = waitpid(pid[i], &stat, 0);
         if (WIFEXITED(stat))
             printf ( "Child %d terminated with status: %d\n" , cpid, WEXITSTATUS(stat));
     }
}
  
// Driver code
int main()
{
     waitexample();
     return 0;
}

输出如下:

Child 50 terminated with status: 100
Child 51 terminated with status: 101
Child 52 terminated with status: 102
Child 53 terminated with status: 103
Child 54 terminated with status: 104

这里, Children pids取决于系统, 但是为了打印所有的孩子信息。

如果发现任何不正确的地方, 或者想分享有关上述主题的更多信息, 请写评论。

木子山

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: