zoukankan      html  css  js  c++  java
  • Linux/UNIX流程关系

    流程关系

    过程组

    除了一个过程,每个过程ID此外。也属于一个进程组。过程基是一个或多个过程的集合。

    通常它们与相同的作业相关联,它接受各种信号从相同终端。

    #include<unistd.h>

    pid_tgetpgrp(void);                 /* POSIX.1version */

    pid_t getpgid(pid_tpid);

    intsetpgid(pid_t pid, pid_t pgid);

    函数getpgrp返回调用进程的进程组ID。

    getpid函数也有此功能。

    进程能够通过调用setpgid来增加一个现有的组或创建一个新进程组。

    会话

    会话是一个或多个进程组的集合。

    一般是由shell的管道将几个进程编成一组的。例如以下所看到的:

    proc1 | proc2 &

    proc3 | proc4 | proc5

    其会话安排例如以下:

    进程调用setsid函数建立一个新会话。

    #include <unistd.h>

    pid_t setsid(void);

    还可调用getsid来返回会话首进程的进程组ID

    #include <unistd.h>

    pid_t getsid(pid_t pid);

    控制终端

    登录时,将自己主动创建控制终端。

    程序与控制终端交互时,为保证程序能读写控制终端的方法是打开文件/dev/tty。在内核中,词特殊文件是控制终端的同义语。假设程序没有控制终端,则打开此设备将失败。

    1.      一个会话能够有一个控制终端

    2.      建立与控制终端联结的会话收进程被称为控制进程

    3.      一个会话中的几个进程组可被分成一个前台进程组以及一个或几个后台进程组

    4.      假设一个会话有一个控制终端。则它有一个前台进程。会话中的其它进程组则为后台进程组

    5.      不管何时键入终端的中断键,就会将中断信号发送给前台进程组的全部进程

    6.      不管何时键入终端的退出键,就会将退出信号发送给前台进程组的全部进程

    7.      假设终端接口检測到的调制解调器已经断开网络。则将挂断信号发送给控进程。

    tcgetpgrp、tcsetpgrp和tcgetsid函数

    #include <unistd.h>

    pid_t tcgetpgrp(int fd);

    int tcsetpgrp(int fd, pid_t pgrp);

    tcgetpgrp函数返回调用前台进程的进程组ID,该前台进程组与在fd上打开的终端相关联。

    假设进程有一个控制终端,则该进程能够调用tcsetpgrp将前台进程组ID设为pgrp。fd必须引用该会话的控制终端。

    #include<termios.h>

    pid_ttcgetsid(int fd);

    该函数识别出控制终端的会话首进程的会话ID。

    作业控制

    作业控制同意在一个终端上启动多个作业(进程组),他控制哪个作业能够訪问终端,以及那些作业也在后台执行。

    catchen123@ubuntu:~$ cat > temp.foo &  在后台启动,但将从标准输入读

    [1] 3894

    chen123@ubuntu:~$

                                      键入回车

    [1]+  Stopped                 cat > temp.foo

    chen123@ubuntu:~$fg %1         使1号作业成为前台作业

    cat >temp.foo                    shell告诉我们如今哪一个作业在前台    

    hello,world                     输入1行,后面接文件结束符(ctrl+D)

    chen123@ubuntu:~$cat temp.foo   检查该行已送入文件

    hello,world

    chen123@ubuntu:~$

    shell在后台启动cat进程,可是当cat视图读其标准输入时,终端驱动程序知道他是个后台作业。于是将SIGTTIN信号送至该后台作业。

    shell检測到其子进程的状态改变,并通知我们该作业已被停止。

    然后。我们用shell的fg 将此停止的作业送入前台执行。

    这样做能够使shell将此作业置入前台进程组。并将继续信号送给进程组。

    由于该作业如今位于前台进程组中。所以它能够读控制终端。

    chen123@ubuntu:~$ cat temp.foo & 在后台运行

    [1] 4125

    chen123@ubuntu:~$hello,world

    [1]+  Done                    cat temp.foo

    chen123@ubuntu:~$stty tostop

    chen123@ubuntu:~$cat temp.foo &

    [1] 4129

    chen123@ubuntu:~$

                                                                     键入回车,发现作业已经停止

    [1]+  Stopped                 cat temp.foo

    chen123@ubuntu:~$ fg %1   在前台恢复停止的作业

    cat temp.foo                                         shell告诉我们如今哪一个作业在前台

    hello,world                                       这是改作业的输出

    总结:在shell命令后面加&,表示该命令将在后台启动。fg命令能够将后台作为送至前台。

    stty tostop能够禁止后台作业输出到终端。

    shell运行程序

    shell是怎样运行程序、以及这与进程组、控制终端和会话等概念的关系.

    shell将前台进程进程放在它自己的进程组中。shell则留在他自己的进程组中。
    ps -o pid,ppid,pgrp,session,tpgid,comm

     PID                   PPID                   PGRP      SESS        TPGID     COMMAND

     4302       4293         4302      4302        4359         bash

     4359       4302         4359      4302        4359         ps

             shell将前台作业(ps)放入它自己的进程组(4359)中。ps命令是组长进程,并是该进程组中唯一的进程。

    进一步讲,此进程组具有控制终端。所以它是前台进程组。我们的登录shell在运行ps命令时是后台进程。但须要注意的是。这两个进程组4302和43509都是同一会话的成员。

      在后台运行此进程:

    ps -o pid,ppid,pgrp,session,tpgid,comm &

    PID                     PPID       PGRP    SESS        TPGID   COMMAND

    4302         4293     4302       4302      4302       bash

    4390        4302       4390     4302       4302       ps

    再一次。ps命令被放入自己的进程组中,可是此时进程组(4302)不再是前台进程组,而是一个后台进程组。

    登录的shell是前台进程组。

    按下列方式在一个管道中运行两个进程:

    ps -opid,ppid,pgrp,session,tpgid,comm | cat

    PID    PPID  PGRP  SESS    TPGID    COMMAND

    4302  4293 4302  4302  4411         bash

    4411  4302 4411  4302  4411         ps

    4412  4302 4411  4302  4411        cat

    两个进程ps和cat1都在一个新进程组中(4411),这是一个前台进程。shell创建将运行管道线中的进程,也就是说ps和cat的父进程都是shell。

    当在后台运行此管道线时。其结果类似。

    ps -opid,ppid,pgrp,session,tpgid,comm | cat &

    PID  PPID PGRP  SESS TPGID COMMAND

     4302 4293  4302  4302 4302 bash

     4440 4302  4440  4302 4302 ps

     4441 4302  4440  4302 4302 cat

    这里须要注意。使用不同的shell,那么它创建的各个进程的顺序是不同样的。以上讨论都是基于Linux上具有作业控制的shell为例。

    假设linux上没有作用控制的shell,那么管道线中最后一个进程是shell的子进程。而运行管道中其它命令的进程则是该最后一个进程的子进程。

    孤儿进程组

    一个其父进程已终止的进程称为孤儿进程,这样的进程由init进程收养。整个进程组也能够称为孤儿。

    孤儿进程组的定义:一个进程组不是孤儿进程组的条件是,该组中每一个成员的父进程要么是该组的一个成员,要么不是改组所属会话的成员。

    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    DoNet:浅淡对delegate的理解
    纹理学习总结
    Vue引发的getter和setter
    JS——判断一个对象是否为空
    使用vue-axios请求geoJson数据报错的问题
    在vue-cli项目中使用echarts
    Vue中的$set的使用
    史上最全的开发和设计资源大全(转--------来源:伯乐在线)
    IOS safari浏览器登陆时Cookie无法保存的问题
    JS中const、var 和let的区别
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4883658.html
Copyright © 2011-2022 走看看