进程间关系和守护进程

一. 进程组/作业/会话
1.进程组

    每一个进程除了有一个进程ID之外, 还属于一个进程组. 进程是一个或多个进程的集合. 通常, 它们与同一个作业向关联, 可以接收来自同一个终端下的各种命令,信号. 每一个进程组都有唯一的进程组 ID. 每一个进程组都可以有一个组长进程. 组长进程的标识是, 其进程组 ID 等于组长进程 ID. 组长进程可以创建一个进程组, 也可以创建该进程组中的进程, 然后终止.只要该组中有一个进程存在, 则该组就存在, 与该组中的组长进程是否存在没有任何关系

2. 相关接口函数

                这里写图片描述
    其中getpgrp 函数用来返回调用进程的进程组 ID, setpid 用来将 pid 进程的进程组 ID 设置为 pgid, 如果两个参数值相等, 则由 pid 指定的进程将会变成进程组组长. 如果 pid 为 0, 则使用调用者的进程 id. 另外, 如果 pgid 为 0, 则由进程 pid 指定的进程 id将会变成进程组 id.一个进程只能为自己的子进程或者为自己设定进程组ID, 但是当这个函数的子进程已经调用了 exec 之后, 父进程就不能再改变子进程的组ID了
    在大多数shell下通常是调用 fork 后让父进程调用 setpgid , 同时也让子进程调用 setpgid.
这里写图片描述    其中 ps 命令常用来显示进程相关信息, 其中选项 a 表示不仅列出当前用户的进程, 也列出其他所有用户进程, x 表示不仅列出有控制终端的进程, 也列出没有控制终端的进程, j 表示列出与作业相关的信息, 同时在上图中可以看出当我们杀死这个进程组中的组长时, 此时该组还是任然存在的(该组中的成员还依旧在). 利用 jobs 命令可以查看后台相关进程

3. 作业

    shell分前台和后台运行的不是进程, 而是作业或者进程组. 一个前台作业可以由多个进程构成, 一个后台作业也可以由多个进程组成, shell可以一次运行一个前台作业和任意多个后台作业, 这就叫做作业控制.
    作业和进程组的区别: 在作业中某个进程创建了一个子进程, 该子进程属于该进程组, 但是该子进程不属于这个作业.一旦作业结束, shell就把自己提到前台, (子进程还在, 但是子进程不属于改作业), 如果原来的前台进程还在, (如果原来的子进程还没有终止), 它将自动成为一个后台进程. 此时我们就可以理解当我们在前台起一个新作业时, 此时shell无法执行, 那是因为shell被放到了后台, 而当改作业退出的时候, shell就被提到了前台.

#include<stdio.h>
#include<unistd.h>int main()
{pid_t id = fork();if(id == -1){return 1;}else if(id == 0){while(1){printf("child(%d)# I am running\n", getpid());}sleep(2);}else{int i = 5;while(i){printf("parent(%d)# I am going to dead\n", getpid());i--;}sleep(2);}return 0;
}
3. 会话

    会话是一个或多个进程组的集合, 一个会话可以有一个控制终端. 这通常是登录到其上的终端设备或者是伪终端设备. 建立与控制终端连接的会话首进程是控制进程. 一个终端下的几个进程组可以被分为一个前台作业以及一个或多个后台作业.所以一个会话中应该包括一个控制进程, 一个前台进程组和多个后台进程组
    通过上面的一些解释, 我们可以得知, 一个作业或者一个进程组由多个进程组成, 而一个会话则由一个前台进程组和多个后台进程组构成.

(1)会话相关接口

                                这里写图片描述
    该函数用于建立一个新的会话, 如果调用函数的进程不是一个进程的组长, 那么就建立新的会话. 此时该进程会变成新的会话首进程, 而此时该进程就会成为新会话中的唯一的一个进程. 而该进程会成为一个新进程组长, 该进程 ID 等于调用该进程的进程 ID. 该进程没有控制端, 如果在调用 setsid 前该进程有一个控制端, 那么原有的这个控制端将会变成一个普通文件不再是控制终端
                                这里写图片描述
    查看进程的会话编号SID, 当 pid = 0 时, 函数返回调用进程会话首进程进程组 ID
    一个作业有多个进程构成, 一个会话由多个作业构成, 其中包括一个前台作业和多个后台作业, 建立一个会话, 就是会建立一个话首进程, 而删除话首进程, 该会话将会退出.

(2)相关命令

     1)将一个作业放到后台去执行时, 只需在可执行程序后面加一个 & 即可. 例如 sleep 100 | sleep 200 &
     2)查看后台作业: jobs
     3) 将一个后台作业由前台提到后台 Ctrl + Z, bg 作业号即可

4. 作业控制相关信号

     后台作业是不能读取终端输入的, jobs 命令可以查看后台相关作业. fg 可以将某个作业从后台提到前台, 但是此时如果该作业是停止状态, 则给作业发送一个 SIGCONT 信号使得该作业能够继续运行. bg 将某个停止的后台作业在后台运行, 也需要给作业发送一个 SIGCONT 信号. 此时该作业就可以在后台运行了.后台作业不能从终端读取数据, 但是后台作业可以往终端写数据

二.守护进程
1. 相关概念

    守护进程也叫做精灵进程, 是运行在后台的一个特殊进程. 它独立于控制终端, 自成进程组, 自成会话, 并且周期性地执行某些任务或者周期性地处理某些发生的事件. Linux 下大多数的服务器就是用守护进程来实现的.
     Linux下有一些进程没有控制终端, 不能直接和用户交互. 其他进程都需要用户登录或运行时创建, 但是守护进程不受用户登录或注销的影响, 它会一直运行.
这里写图片描述
    通过 ps 命令查看系统中的进程, 其中 PPID 是父进程编号, PID 是当前进程编号, PGID 是进程组ID, SID 是会话 ID, TTY 表示终端名称, TPGID 表示会话组ID, STAT 表示进程状态, UID表示用户ID, COMMAND 表示命令字符串可以看到 凡是 TPGID 为 -1 的都是守护进程, COMMAND 用 [] 括起来的都是内核线程, 这些线程都是在内核中创建, 没有用户代码, 没有程序文件以及命令行, 通常以 k 开头. 守护进程一般以 d 结尾的名字

2. 守护进程的创建
#include<unitd.h>
pid_t setsid();
调用成功时返回创建的会话ID, 失败时返回 -1

    该函数在调用的时候必须保证调用的进程不能是进程组组长, 为了保证该点, 就先 fork 然后再让子进程去执行 setsid 即可. 其中在创建会话时, 子进程就会自成组长, 即子进程的 id 就会成为其组长的id, 并且该进程也会自成会话, 即会话 ID就是该进程的 ID, 并且如果当前进程有一个会话终端的时候, 它将会失去原有的会话终端, 即原来的会话终端还是打开的, 仍然可以读写, 但是将会变成一个普通文件, 不再是控制终端了.

#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<stdlib.h>void mydaemon()
{int fd0;pid_t id;struct sigaction sa;//1. 屏蔽umaskumask(0);id = fork();if(id < 0){perror("fork");exit(1);}//2. fork 父进程退出, 子进程运行if(id > 0){exit(0);}if(setsid() < 0){perror("setsid");exit(1);}//3. 初始化sasigemptyset(&sa.sa_mask);sa.sa_handler = SIG_IGN;sa.sa_flags = 0;//4. 对SIGCHLD信号忽略, 防止产生僵尸进程if(sigaction(SIGCHLD, &sa, NULL) < 0){perror("sigaction");exit(1);}fd0 = open("/dev/null", O_RDWR);close(0);dup2(fd0, 1);dup2(fd0, 2);
}int main()
{mydaemon();while(1){sleep(1);}return 0;
}

        这里写图片描述
    关闭当前终端, 打开另外一个终端时, 继续查看, 会发现原来的会话还存在, 于是我们可以得出结论, 守护进程单独成组, 单独成回话, 不受控制终端控制
        这里写图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/384019.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

猴子偷桃问题

http://blog.csdn.net/snow_5288/article/details/52561882 问题描述&#xff1a; /*有一群猴子&#xff0c;去摘了一堆桃子*/ /*商量之后决定每天吃剩余桃子的一半*/ /*当每天大家吃完桃子之后&#xff0c;有个贪心的小猴都会偷偷再吃一个桃子*/ /*按照这样的方式猴子们每天都…

网络相关基础概念

一. 相关基础概念 1.计算机网络的特点 (1)连通性:计算机网络使得上网的用户都能够彼此相连, 好像用户的计算机可以直接相连     (2)资源共享:资源共享可以是信息共享, 软件共享, 硬件共享等等. 由于网络的存在, 使得用户感觉资源就在自己身边 2. 网络 网络是由若干结点和…

linux线程同步(2)-条件变量

https://www.cnblogs.com/yuuyuu/p/5140875.html linux线程同步(2)-条件变量 一.概述 上一篇&#xff0c;介绍了互斥量。条件变量与互斥量不同&#xff0c;互斥量是防止多线程同时访问共享的互斥变量来保护临界区。条件变量…

点对点数据链路层

数据链路层的主要功能将数据转换为相应的比特流使用的信道主要有点对点的信道方式(一对一的方式), 以及广播的信道方式 一. 点对点信道的数据链路层 1. 数据链路和数据帧 链路就是从一个结点连接到相邻结点的一段物理线路(有线或者无线), 期间不准有任何的交换结点, 因此两台…

linux线程同步(1)-互斥量

http://www.cnblogs.com/yuuyuu/p/5140251.html 一.概述 互斥量是线程同步的一种机制&#xff0c;用来保护多线程的共享资源。同一时刻&#xff0c;只允许一个线程对临界区进行访问。 互斥量的工作流程&#xff1a;创建一个…

linux线程同步(3)-读写锁

http://www.cnblogs.com/yuuyuu/p/5143881.html 一.概述 读写锁与互斥量的功能类似&#xff0c;对临界区的共享资源进行保护&#xff01;互斥量一次只让一个线程进入临界区&#xff0c;读写锁比它有更高的并行性。读写锁有…

linux线程同步(5)-屏障

http://www.cnblogs.com/yuuyuu/p/5152560.html 一.概述 barrier(屏障)与互斥量&#xff0c;读写锁&#xff0c;自旋锁不同&#xff0c;它不是用来保护临界区的。相反&#xff0c;它跟条件变量一样&#xff0c;是用来协同多…

Linux多线程与同步

https://www.cnblogs.com/freedomabcd/p/7774743.html 典型的UNIX系统都支持一个进程创建多个线程(thread)。在Linux进程基础中提到&#xff0c;Linux以进程为单位组织操作&#xff0c;Linux中的线程也都基于进程。尽管实现方式有异于其它的UNIX系统&#xff0c;但Linux的多线程…

内存管理(二)

页面置换算法 当发生缺页中断的时候, 系统会在内存中选择一个页面将其换出内存, 而当换出内存的时候如果该页面的内容在内存中发生修改,则必须将该新数据重新写回到磁盘, 然后再将需要换进的数据覆盖掉原来的数据, 而当该数据在内存中没有被修改的时候, 此时就直接用需要换进的…

数据链路层:基本概念

数据链路层的定义 对数据链路层有对上的网络层接口. 对下提供物理层的接口. 定义合适的传输差错率 对传输流进行管理, 以免快速的传输的数据被淹没. 比如发送端发送信号太快, 接受方接受速度较慢, 此时数据链路层就需要提供一定的功能解决这个问题 物理层上传输的基本单元是…

数据链路层: 可靠性传输 六个协议

可靠性传输 1. 差错控制 发送方将数据帧发送, 但是当发送方发送的是一个 1的时候此时接受方却接受的是一个 0. (1)校验 接收方如果帧校验接受到的帧没有问题, 则对发送方发送一个肯定性的确认, 当对这个数据帧进行校验发现这个帧有问题的时候, 此时接受方一种是将这个数据帧…

c语言实现配置文件的读写

配置文件的格式如下&#xff1a; key1 value1 key2 value2 . . . 名值对以一个链接&#xff0c;一条记录以换行符分割 头文件&#xff1a; #include<stdio.h> #include<stdlib.h> #include <string.h> 函数原型&#xff1a; void trim(char *strIn, char *…

数据链路层: HDLC

一. 协议机 发送方和接收方. 同时有限状态机把协议形式化为一个四元组 (S,M,I,T), 其中你S表示进程和信道可能进入的集合, M 表示数据帧的状态, I 表示进程的初始状态, T 表示两两状态之间的转化. 每个系统状态可以分为发送状态, 接受状态和信道状态. 把状态用一个点进行表示,…

bob-tong 字符串函数之Strtok()函数

https://www.cnblogs.com/Bob-tong/p/6610806.html Strtok()函数详解&#xff1a; 该函数包含在"string.h"头文件中 函数原型&#xff1a; char* strtok (char* str,constchar* delimiters ); 函数功能&#xff1a;   切割字符串&#xff0c;将str切分成一个个子…

数据链路层:SLIP(串型线路IP) PPP(点对点协议)

SLIP 没有差错控制, 传输时必须知道对方IP, 传输使用于低速业务 19.2k.应用非常受限 PPP协议 1. PPP协议功能 处理错误检测 支持多协议(IP, IPX, DECnet 等) 连接时允许协商 IP 地址 允许身份验证 2. PPP 的组成 串型链路上封装数据报, 即支持异步链路也支持面向 比特…

strpbrk函数

http://blog.csdn.net/tommy_wxie/article/details/7554332 函数原型&#xff1a;extern char *strpbrk(char *str1, char *str2) 参数说明&#xff1a;str1待比较的字符串&#xff0c;str2为指定被搜索的字符串。 所在库名&#xff1a;#include <string.h> …

网络层网络层服务及其 IP 地址

ARP 协议功能 将 IP 地址通过广播(一个网段, 不能跨路由器), 目标 MAC 地址是FFFFFFFF 解析目标IP地址的 MAC 地址. IP 协议 网络层的一个协议, 是一个协议的统称, 包括 ARP(地址解析协议) 协议, ICMP(网络控制报文协议) 协议, IGMP(网际组管理协议) 协议. 其中 ICMP 和 IG…

传输层:IP 地址解析 路由转发

IP 地址与硬件地址 1. 地址解析 通过IP地址将其如何转换为 MAC 地址.解决同一个局域网上的主机或路由的 IP 地址和硬件地址的映射问题. 即以太网上除了主机还有路由. 即如果发出的请求所有的主机都没有做出相应, 那么该以太网上的路由会对其做出响应. (1) 以太网内部主机与…

网络层:构成超网(CIDR)

CIDR构成超网 CIDR消除了原来的传统的 A,B, C, D类地址, 使用了各种网络前缀来代替原来分类地址中的网络号和子网号, IP 地址由原来的三级分类又变成了两级分类. 其中网络号和子网号是一个随机的长度. 其中 CIDR 也可以使用 / 的形式来表示, 其中在 / 前面写上网络前缀的位数.…

网络层:网关协议

一. 网关 所谓的网管即就是之前路由器的名字, 即路由器和网关是一个东西 二. 内部网关协议 1. RIP协议 路由信息协议 RIP 是内部网关协议 IGP中最先得到的广泛使用的协议. 同时 RIP 是一种分布式基于距离向量的路由选择协议. RIP 协议要求网络中的每一个路由都必须维护自己…