APUE 第八章知识点

发布时间 2023-04-10 07:26:00作者: 闲云潭影

APUE 第八章知识点:

fork中子任务和父任务之间不继承的关系有:

  1. 返回值
  2. PID
  3. 子进程的time都会被变成0
  4. 在父进程之中的文件锁不会被子进程集成
  5. alarm会在子进程中被清零
  6. 所有信号量会在子进程中清零

Fork 和vfork的区别:
vfork 的子进程会先运行,直到调用_exit 或者exit之后才会运行父进程
vfork 的子进程只是在父进程的空间进行程序的处理而不是拷贝整个空间。:w

wait 和 waitpid 函数:
pid_t wait(int *statloc);
pit waitpid(pid_t pid, int *statloc, int options);

wait example:

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

int main() {
  pid_t pid;
  int status;

  pid = fork(); // create a child process

  if (pid < 0) { // error occurred
    printf("Fork failed.\n");
    exit(1);
  } 
  else if (pid == 0) { // child process
    printf("Child process is running.\n");
    sleep(5); // sleep for 5 seconds
    printf("Child process is done.\n");
    exit(0);
  }
  else { // parent process
    printf("Parent process is waiting for child process to complete.\n");
    wait(&status); // wait for child process to complete
    printf("Parent process is done.\n");
  }
  return 0;
}

The parent process wait for child process finished.
status save the child exit status.

WIFEXIT Example:

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

int main() {
  pid_t pid;
  int status;

  pid = fork(); // create a child process

  if (pid < 0) { // error occurred
    printf("Fork failed.\n");
    exit(1);
  } 
  else if (pid == 0) { // child process
    printf("Child process is running.\n");
    sleep(5); // sleep for 5 seconds
    printf("Child process is done.\n");
    exit(42);
  }
  else { // parent process
    printf("Parent process is waiting for child process to complete.\n");
    wait(&status); // wait for child process to complete

    if (WIFEXITED(status)) {
      int exit_status = WEXITSTATUS(status);
      printf("Child process exited normally with status %d.\n", exit_status);
    }
    else {
      printf("Child process did not exit normally.\n");
    }

    printf("Parent process is done.\n");
  }
  return 0;
}

Macro definition

Macro Description
WIFEXITED(status) True if status was returned for a child that terminated normally. In this case, we can execute WEXITSTATUS(status)to fetch the low-order 8 bits of the argument that the child passed to exit, _exit, or _Exit.
WIFSIGNALED(status) Tr ue if status was returned for a child that terminated abnormally, by receipt of a signal that it didn’t catch. In this case, we can execute WTERMSIG(status) to fetch the signal number that caused the termination. Additionally, some implementations (but not the Single UNIX Specification) define the macro WCOREDUMP(status) that returns true if a core file of the terminated process was generated.
WIFSTOPPED(status) Tr ue if status was returned for a child that is currently stopped. In this case, we can execute WSTOPSIG(status) to fetch the signal number that caused the child to stop
WIFCONTINUED(status) True if status was returned for a child that has been continued after a job control stop (XSI option; waitpid only)

waitpid

pid_t waitpid(pid_t pid , int *status , int options)
pid == -1:
Waits for any child process. In this respect, waitpid is equivalent to wait.
pid > 0:
Waits for the child whose process ID equals pid.
pid == 0:
waits for any child whoese process group id equals that of the calling process
pid < -1:
waits for any child whoes process group ID equals the absolute value of pid.

options:

  1. WCONTINUED:
    if the implementation supports job control, the status of any child specified by pid that has been continued after being stopped, but whose status has not yes been reported is returned(XSI option)
  2. WHOHANG:
    The waitpid function will not block if a child specified by pide is not immediately available. in this case the return value is 0;
    Note: when the child process is still running the father process will return 0 immediately and doing another task.
  3. WUNTRACED:
    if the implementation supports job control, the status of any child specified by pid that has stopped and whose status has not been reported since it has stopped, is returned.
    Note: when the child process receive the stop signal, this option can catch it.
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>

int main() {
    pid_t child_pid = fork();

    if (child_pid == 0) {
        // Child process
        printf("Child process running\n");
        raise(SIGSTOP);
        printf("Child process exiting\n");
        return 0;
    } else if (child_pid > 0) {
        // Parent process
        printf("Parent process waiting for child to stop\n");

        int status;
        pid_t stopped_child_pid = waitpid(child_pid, &status, WUNTRACED);

        if (stopped_child_pid == -1) {
            perror("waitpid");
            return 1;
        }

        if (WIFEXITED(status)) {
            printf("Child process exited normally with status %d\n", WEXITSTATUS(status));
        } else if (WIFSIGNALED(status)) {
            printf("Child process terminated by signal %d\n", WTERMSIG(status));
        } else if (WIFSTOPPED(status)) {
            printf("Child process stopped by signal %d\n", WSTOPSIG(status));
        } else {
            printf("Unknown exit status\n");
        }

        return 0;
    } else {
        // Error
        perror("fork");
        return 1;
    }
}

waitid

int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options)

idtype

Constant Description
P_PID wait for a particular process: id constains the process ID of the child to wait for
P_PGID wait for any child process in a particular process group: id contains the process group ID of the children to wait for.
P_ALL Wait for any child process: id is ignored

options:

Constant Description
WCONTINUED Wait for a process that has previously stopped and has been continued and whose status has not yet been reported
WEXITED Wait for processes that have exited
WHOHANG Return immediately instead of blocking if there is no child exit status available
WNOHANG Retrun immediately instead of blocking if there is no child exit status available
WNOWAIT Do not destroy the child exit status. The child's exit status can be retrieved by a subsequent call to wait, waitid or waitpid
WSTOPPED Wait for a process that has stopped and whose status has not yet been reported