• 系统编程--进程关系与守护进程


    1.终端登录
    登录过程:内核--->init[进程ID=1]--->(fork)init--->(exec)getty--->(exec)--->login
    登录结束过程:进程1=init->登录shell<->终端设备驱动程序<->使用终端的用户
    2.网络登录
    如下图

    3.进程组
    1).每个进程属于一个进程组,这个进程组从同样的终端获得信号
    函数getpgrp返回调用进程的进程组ID,结果也用pid_t表示:

    #include <unistd.h>
    pid_t getpgrp(void);
    //返回调用进程的进程组ID

    2)SUS定义getpgid函数作为一个XSI扩展来效仿1)中函数的行为

    #include <unistd.h>
    pid_t getpgid(pid_t pid);
    //成功返回进程组ID,错误返回-1

    如果pid为0,返回调用进程的进程组ID。因而getpgid(0)等价于getpgrp();

    3).每个进程组可以有一个进程组长。这个组长和它的进程组ID相等的进程ID于来标识(Leader的ProcessID = Process Group ID)。可能一个进程组长会创建一个进程组、创建这个组的进程,然后终止。只要至少有一个进程在这个组里,这个进程组便仍然存在,不管进程组长是否终止。一个进程加入一个存在的进程组或创建一个新的进程组,通过调用setpgid:

    #include <unistd.h>
    int setpgid(pid_t pid, pid_t pgid);
    //成功返回0,错误返回-1

    setpgid函数将pid进程的进程组ID设置为pgid。如果两个参数相等,则由pid指定的进程成为进程组长。如果pid为0,那么使用调用者的进程ID。同样,如果pgid为0,由pid指定的进程ID作为进程组ID被使用。
    PS:一般使进程设置其子进程的进程组ID,并且使子进程设置其中经的进程组ID

    4.会话

    会话是一个或多个进程组的集合,下面一个会话中有三个进程组
     

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

    #include <unistd.h>
    pid_t setsid(void);
    //返回进程组ID;错误返回-1

    如果调用进程不是一个进程组长,那么这个函数创建一个新的会话。有三件事发生:

    1).该进程变成新会话的会话首进程。(会话首进程是创建该会话的进程。)该进程是这个新会话里的唯一进程。
    2).该进程变为一个新进程组的进程组长。新进程组ID就是该调用进程的进程ID。
    3).该进程没有控制终端。如果进程在调用setsid之前有一个控制终端,那么这个关联被中断。
    PS:如果调用者已经是一个进程组长,那么这个函数返回一个错误。为了保证不出现这种情况,通常的做法是调用fork,然后使父进程终止,而让子进程继续。

    getsid函数返回一个进程的会话领导的进程组ID

    #include <unistd.h>
    pid_t getsid(pid_t pid);
    //返回会话领导的进程组ID,错误返回-1

    如果pid为0,getsid返回调用进程的会话领导的进程组ID。由于出于安全原因考虑,一些实现可能有如下限制:如果pid不属于调用者所在的会话,调用进程不能得到会话领导的进程组ID。

    5.控制终端
    会话和进程组有几个其它的特性::
    1).会话可以有单一的控制终端。这通常是在登录到其上的终端设备(在终端登录的情况下)或者伪终端设备(在网络登录的情况下)。
    2).建立与控制终端连接的会话首进程被称为控制进程。
    3).一个会话里的几个进程组可以被分为一个前台进程组和一个或多个后台进程组。
    4).如果一个会话有一个控制终端,那么它有一个前台进程组,而在这个会话里的所有其它进程组都是后台进程组。
    5).每当我们输入终端的中断键(经常是DELETE或Control-C),就会将中断信号发送给前台进程组的所有进程。
    6).无论何时我们输入终端的退出键(经是Control+),就会将退出信号发送给前台进程组的所有进程。
    7).如终端接口检测到调制解调器或者网络连接断开连接,则将挂起信号发送给控制进程(会话首进程)。


    1.守护进程的特征
        守护进程也称精灵进程是生存期长的一种进程,它们常常在系统引导装入时启动,在系统管比时终止。守护进程没有控制终端,所以它们是在后台运行的。守护进程是一种很有用的进程。 Linux的大多数服务器就是用守护进程实现的。比如,Internet服务器inetd,Web服务器httpd等。同时,守护进程完成许多系统任务。比如,作业规划进程crond,打印进程lpd等。
        所有守护进程都以超级用户(用户ID为0)的优先权运行。没有一个守护进程具有控制终端,控制名称设置为(?)、终端前台进程组ID设置为-1。除update以外的所有守护进程都是组的首进程,对话期的首进程,而且是这些进程组和对话期中的唯一进程。所以的守护进程的父进程都是init进程。
        守护进程最重要的特性是后台运行。在这一点上DOS下的常驻内存程序TSR与之相似。其次,守护进程必须与其运行前的环境隔离开来。这些环境包括未关闭的文件描述符,控制终端,会话和进程组,工作目录以及文件创建掩模等。这些环境通常是守护进程从执行它的父进程(特别是shell)中继承下来的。最后,守护进程的启动方式有其特殊之处。它可以在Linux系统启动时从启动脚本/etc/rc.d中启动,可以由作业规划进程crond启动,还可以由用户终端(通常是shell)执行。
     
    2.编程规则
    1).首先做的是调用fork,然后使父进程exit
    2).调用setsid以创建一个新对话期
    3).将当前工作目录更改为根目录
    4).将文件方式创建屏蔽字设置为0
    5).关闭不再需要的文件描述符
    6).某些守护进程打开/dev/null使其具有文件描述符0,1,2,这样,任何一个试图读标准输入、写标准输出或标准出错的库历程都不会产生任何效果。
     
    3.出错记录
    大多数守护进程使用syslog设施(守护进程出错记录措施)。下图显示了syslog设施的详细组织结构。

    4.守护进程的惯例
    1).如果守护进程使用一个锁文件,那么文件通常存储在/var/run目录下。
    2).如果守护进程支持配置选项,那么它们通常被存储在/etc目录中。
    3).守护进程可以通过命令行启动,但是通常它们是由系统初始化脚本之一(/etc/rc*或/etc/init.d/*)启动的
    4).如果一守护进程有一个配置文件,那么当该守护进程启动时,它读该文件,但是此之后一般就不会再次查看它
  • 相关阅读:
    批量修改文件编码
    RAII机制
    C++20新特性一:模块Module
    vue 使用v-for遍历对象属性
    Chrome 91 本地跨域无法携带cookies问题解决
    Vue 函数式组件的使用技巧
    URL编码解决中文字符乱码(encodeURIComponent和decodeURIComponent)
    vue的provide/inject实现响应式数据监听
    vue3之watch监听
    Vue3: 知识总结: hooks
  • 原文地址:https://www.cnblogs.com/tla001/p/6545780.html
Copyright © 2020-2023  润新知