Linux 进程间关系和守护进程

Linux 进程间关系和守护进程

进程间关系

1. 进程组

进程组是一个或多个进程的集合。每个进程的PCB中除了有自己的PID外,还有PGID。每个进程组有唯一的一个进程组ID(PGID)。每个进程组可以有它的一个组长进程。组长进程是创建该进程组的进程,进程组ID等于组长进程PID。组长进程的子进程同样属于该进程组,也可以说是有亲缘关系的进程同属于一个进程组。只要进程组中还有一个进程存在,那么这个进程组就存在。

2. 作业

为了完成某一项任务而组织起来的一组进程,叫做作业。作业分为前台作业和后台作业。一个前台作业或者后台作业均可以由多个进程组成。

2.1 作业与进程组的区别

进程组中的一个进程创建的子进程仍然属于该进程组;而一个作业中的进程所创建出的子进程则不属于改作业。

2.2 作业与Shell的联系

Shell可以运行一个前台作业和人一多个后台作业。一旦前台作业运行结束,Shell就把自己自动提到前台,如果原来的前台进程还存在,那么它自动变为后台进程组。

3. 会话

会话是一个或多个进程组的集合。当每打开一个终端就开启了一个会话。建立与控制终端链接的会话首进程被称为控制进程。控制进程有能力再建立一个新的会话。一个会话中的进程组可被分为一个前台进程组以及任意个后台进程组。一个会话应包含控制进程、一个前台进程组、任意个后台进程组。

4. 作业控制

前面讲到,作业分为前台作业和后台作业。将作业从后台提到前台后从前台放到后台,称为作业控制。

jobs: 查看当前会话的所有作业
fg:将一个后台作业提到前台运行。当该后台作业处于运行态,则直接提到前台运行;当改后台作业处于停止状态,则还要给作业中的每个进程发送SIGCONT信号使整个作业继续运行。
bg:让某个停止的作业在后台继续运行
Ctrl+z:将正在前台运行的作业提至后台,同时改为停止状态。

守护进程

1. 什么是守护进程?

守护进程也成为精灵进程(Daemon),是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或是处理某些发生的事件。守护进程自成进程组、自成会话、不受用户登录和注销的影响。
它存在的意义在于能够7*24小时不间断的对外提供服务或者完成某项任务。
在TPGID一栏写着的-1的都是没有控制终端的进程,即守护进程。

2. 创建守护进程的两种方法

2.1 setsid函数

函数原型如下:

#include<unistd.h>
pid_t setsid(void);
//该函数调用成功时返回创建的新的会话的id,失败返回-1

调用这个函数之前,当前进程不能是进程组的组长,否则该函数出错返回-1。为什么有这个前提条件呢?要把一个进程改为守护进程,那么这个进程之后肯定是独立于控制终端之外的,也就意味这控制终端不知道它的存在,检测不到它的PID。若它是进程组的组长,那么对于该进程组下的进程而言,它们到底是属于哪个进程组呢?这就出问题了。所以在调用该函数之前,一般先fork出子进程,把子进程变为守护进程。

注意:在调用完setsid之后,肯能需要做的三件事:
1. 设置信号屏蔽字。可以用signal注册信号也可以用信号集操作函数
2. 改变工作目录 函数为chdir
3. 关闭不需要的文件描述符close或者重定向到/dev/null。 函数为dup2

#include<unistd.h>
#include<signal.h>
#include<stdlib.h>                                                                                  
int main()
{
    pid_t pid = fork();
    if(pid > 0)
    {   
        exit(0);
    }   
    else if(pid == 0)
    {   
        setsid();
        signal(SIGCHLD, SIG_IGN);
        chdir("/");
        close(0);
        close(1);
        close(2);
        while(1);
    }   
}

将上述代码写入daemon.c文件中,编译后运行。如下图所示可以看到将子进程变成了守护进程,同时将工作目录切换到根目录。并且关闭了标准输入、标准输出、标准错误:

2.2 daemon函数

函数原型如下:

#include<unistd.h>
int daeomon(int nochdir, int noclose);  

参数说明:
nochdir为1,表示不改变工作目录;为0表示改变工作目录。
noclose为1,表示不从定向文件描述符(保持默认);为0表示将文件描述符重定向到/dev/null文件下。

nohup命令

nohup 命令

用途:不挂断地运行命令。

语法:nohup Command [ Arg … ] [ & ]

描述:nohup 命令运行由 Command 参数和任何相关的 Arg 参数指定的命令,忽略所有挂断(SIGHUP)信号。在注销后使用 nohup 命令运行后台中的程序。要运行后台中的 nohup 命令,添加 & 符号到命令的尾部。

无论是否将 nohup 命令的输出重定向到终端,输出都将附加到当前目录的 nohup.out 文件中。如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中。如果没有文件能创建或打开以用于追加,那么 Command 参数指定的命令不可调用。如果标准错误是一个终端,那么把指定的命令写给标准错误的所有输出作为标准输出重定向到相同的文件描述符。

如果使用nohup命令提交作业,那么在缺省情况下该作业的所有输出都被重定向到一个名为nohup.out的文件中,除非另外指定了输出文件:

nohup command > myout.file 2>&1 &
在上面的例子中,输出被重定向到myout.file文件中。若不关心程序的输出,则可以将文件改为/dev/null。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值