📜  在C中等待系统调用

📅  最后修改于: 2021-05-25 21:26:52             🧑  作者: Mango

先决条件:前叉系统调用
对wait()的调用将阻止调用进程,直到其子进程之一退出或接收到信号为止。子进程终止后,父进程在等待系统调用指令后继续执行。
子进程可能由于以下任何原因而终止:

  • 它调用exit();
  • 它从main返回(int)
  • 它从操作系统或其他进程接收信号,其默认操作是终止。

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()返回时,它们还通过指针(如果status不为NULL )定义退出状态(告诉我们,进程为何终止)。
如果任何进程没有子进程,则wait()立即返回“ -1”。
注意:“由于环境问题,此代码无法在简单的IDE中运行,因此请使用终端来运行代码”
例子:

CPP
// C program to demonstrate working of wait()
#include
#include
#include
#include
 
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;
}


C
// C program to demonstrate working of wait()
#include
#include
#include
 
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;
}


C
// C program to demonstrate working of status
// from wait.
#include
#include
#include
#include
 
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;
}


C
// C program to demonstrate waitpid()
#include
#include
#include
#include
 
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;
}


输出:

Parent pid = 12345678 
Child pid = 89546848 

C

// C program to demonstrate working of wait()
#include
#include
#include
 
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
HC: Bye
CT: child has terminated    // this sentence does 
                            // not print before HC 
                            // because of wait.
Bye

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

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

要查找有关状态的信息,我们使用
WIF ….macros
1. WIFEXITED(状态) :孩子正常退出
WEXITSTATUS(status) :子项退出时返回代码
2. WIFSIGNALED(状态) :由于没有捕获到信号,孩子退出了
WTERMSIG(status) :给出终止信号的编号
3. WIFSTOPPED(状态) :孩子已停止
WSTOPSIG(status) :给出停止信号的编号

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

例子:
检查以下程序的输出。

C

// C program to demonstrate working of status
// from wait.
#include
#include
#include
#include
 
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()函数。

选项参数

  • 如果为0表示没有选项,则父级不必等待终止子级。
  • 如果WNOHANG表示父级不等待,如果子级不终止,则只需检查并返回waitpid()。(不阻止父级进程)
  • 如果child_pid为-1,则表示任意子级,这里waitpid()的工作方式与wait()相同。

waitpid()的返回值

  • 孩子的pid(如果孩子退出了)
  • 0,如果使用WNOHANG并且child尚未退出。

C

// C program to demonstrate waitpid()
#include
#include
#include
#include
 
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
想要从精选的最佳视频中学习和练习问题,请查看《基础知识到高级C的C基础课程》。