• 6.进程间关系


    一. 终端

    进程里记录了自己的控制终端是谁,使用ps ajx 命令,其中的tty部分代表当前使用的终端是什么。打问号代表这个进程是没有控制终端的,有控制终端的会记录控制终端的编号是什么

    tty 代表字符终端, pts 代表图形界面终端, /dev/tty,指向当前所用的终端

    二.进程组

    进程组是一个或多个进程的集合,进程组ID是一个正整数。用来获得当前进程组的函数

    getpgid(pid_t pid); // 获得指定进程ID的进程组ID,如果传递0,则代表获取当前进程的进程组ID
    pid_t getpgrp(void)

    组长进程就是进程组ID与进程ID相等的进程。组长进程可以创建一个进程组, 若组长进程此时终止, 则该进程组的其它进程的进程组号仍然不变,当这个进程组的最后一个进程消亡之后,该进程组才真正消亡。

    例1:getpgid和getpgrp的使用:

    getpgrp

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    
    int main()
    {
    
        pid_t pid;
        pid = fork();
        if (pid > 0) {
            printf("I am parent, pid is: %d, pgid isi: %d
    ", getpid(), getpgrp());    
        } else if (pid == 0) {
            printf("I am child, pid is: %d, pgid is: %d
    ", getpid(), getpgrp());
        } else {
            perror("fork");
            exit(1);
        }
        return 0;
    }

    getpgid

    #include <unistd.h>
    #include <stdio.h>
    
    int main()
    {
    
        printf("current progress group id is: %d
    ", getpgid(0));
        while (1);
        return 0;
    }

    运行结果:

    current progress group id is: 5665

    一个进程可以为自己或子进程设置进程组ID

    int setpgid(pid_t pid, pid_t pgid)
    如改变子进程为新的组,应在fork后,exec前使用, 非root进程只能改变自己创建的子进程,或有权限操作的进程

    例:使用setpgid设置新的进程组

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    
    int main()
    {
    
        pid_t pid;
        pid = fork();
    
        if (pid > 0) {
            sleep(5);
            setpgid(pid, pid);
            while (1);
        } else if (pid == 0) {
            while (1) {
                printf("I am child, pid is: %d, gid is: %d
    ", getpid(), getpgrp());
                sleep(2);
            }
        } else {
            perror("fork");
            exit(1);
        }
        return 0;
    }

    运行结果:

    I am child, pid is: 5758, gid is: 5757
    I am child, pid is: 5758, gid is: 5757
    I am child, pid is: 5758, gid is: 5757
    I am child, pid is: 5758, gid is: 5758
    I am child, pid is: 5758, gid is: 5758
    I am child, pid is: 5758, gid is: 5758

    三.会话

    ps ajx 中的SID栏目就是指一个会话ID, 会话ID是跟shell绑定的。会话的典型应用场景在于:

    当用户退出shell时,由该shell启动的所有进程将收到这个信号(SIGHUP), 默认动作为终止进程。向一个进程发送0号信号,测试这个进程是否存活。
    我们可以使用下列函数使一个程序成为一个新的会话(当控制终端结束之后,该进程还可以正常运行)

    pid_t setsid(void)

    使用该函数需要注意:

    1. 调用进程不能是进程组的组长进程, 当调用完毕后,调用进程会变成新会话首进程, 同时成为一个新进程组的组长进程。
    2.需要有root权限,ubuntu不需要。
    3.新会话会丢弃原有的控制终端,该会话没有控制终端。
    4.若调用进程是组长进程,则出错返回。
    5.建立新会话时,先调用fork,父进程终止,子进程调用。

    例:

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    int main()
    {
        pid_t pid;
        pid = fork();
        
        if (pid == 0) {
            
            printf("I am child process, pid is: %d, gid is: %d, sid is: %d
    ", getpid(), getpgrp(), getsid(0));
            setsid();        
            printf("I am child process, pid is: %d, gid is: %d, sid is: %d
    ", getpid(), getpgrp(), getsid(0));
            while(1);
        } else if (pid < 0) {
            perror("fork");
            exit(1);
        }
        
        return 0;
    }

    运行结果:

    I am child process, pid is: 5960, gid is: 5959, sid is: 5795
    I am child process, pid is: 5960, gid is: 5960, sid is: 5960

    其中的getsid(0) 用于查看当前进程的会话ID  

     

  • 相关阅读:
    学号 20175212童皓桢 《Java程序设计》第8周学习总结
    20175212童皓桢 在IDEA中以TDD的方式对String类和Arrays类进行学习
    20175212童皓桢 Java实验二-面向对象程序设计实验报告
    学号20175212 《Java程序设计》第7周学习总结
    20175212童皓桢 结对编程项目-四则运算 第二周
    20175212童皓桢 类定义
    20175212童皓桢 《Java程序设计》第六周学习总结
    20175212童皓桢 结对编程项目-四则运算 第一周
    学号 20175212童皓桢 第五周迭代选做题学习
    学号 2018-2019-20175212 童皓桢《Java程序设计》第5周学习总结
  • 原文地址:https://www.cnblogs.com/yongdaimi/p/8657661.html
Copyright © 2020-2023  润新知