进程描述+PCB+fork用法介绍

进程控制块PCB

  1. 进程id:系统中每个进程有唯一的id,在c语言中用pid_t 表示,其实就是非负整数
  2. 进程的状态:就绪,运行,挂起,停止,僵尸等状态
  3. 进程切换是需要保存和恢复的一些cpu寄存器
  4. 描述虚拟地址空间的信息
  5. 描述控制终端的信息
  6. 当前工作目录
  7. umask掩码
  8. 文件描述符表,包含很多指向file 结构体的指针
  9. 信号相关信息
  10. 用户id和组id
  11. 控制终端,session和进程组
  12. 进程可以使用的资源上限

进程控制fork

fork的作用是根据一个现有的进程辅助出一个新进程,原来的进程称为父进程,新进程称为子进程。系统中同时运行着很多的进程,这些进程都是从最初只有一个进程开始一个一个复制出来的。

在shell下输入命令可以运行一个程序,是因为shell进程在读取用户输入的命令之后会调用fork复制出一个新的shell进程。

fork 代码实例

int main() {
    std::string msg;
    int n;
    pid_t pid = fork();
    if(pid < 0){
        perror("fork");
        exit(1);
    }
    if(pid == 0){
        // 子进程
        msg = "child process~\n";
        n = 6;
    }else{
        // 父进程
        msg = "parent process~\n";
        n = 3;
    }
    while (n> 0){
        std::cout << msg;
        sleep(1);
        n--;
    }
    return 0;
}

上面程序,当pid == 0 时,就是子进程执行逻辑,不等于0的时候就是父进程的代码执行逻辑。

上面的小程序运行结果是:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sBQoTOnI-1686839557283)(null)]

可以发现上面的结果中有bash 进程的参与。这是因为父进程在3s后就死掉了,然后子进程就成了孤儿进程。他会给另一个进程去托管。其实上面的进程关系是bash->parent->child 。当parent死掉后,bash进程作为他的父进程会恢复自己的状态 。我们再将程序改动一下,打印一下,各个进程的pid,来看看最后作为孤儿进程的child process 被哪个进程托管了。

getPid + getPPid

int main() {
    std::string msg;
    int n;
    pid_t pid = fork();
    if(pid < 0){
        perror("fork");
        exit(1);
    }
    if(pid == 0){
        // 子进程
        n = 6;
        while(n > 0){
            std::cout << "self child pid = " << getpid() << "parent pid = " << getppid() << std::endl;
            sleep(1);
            n--;
        }
    }else{
        // 父进程
        n = 3;
        while(n > 0){
            std::cout << "self parent pid = " << getpid() << "parent pid = " << getppid() << std::endl;
            sleep(1);
            n --;
        }

    }
    return 0;
}

进程描述+PCB+fork用法介绍_第1张图片

上面的结果可以看出 后面的孤儿进程 被 pid 为 1的系统的第一个进程给接管了。

你可能感兴趣的:(计算机操作系统,bash,开发语言)