进程间关系和守护进程

一. 进程组/作业/会话
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,一经查实,立即删除!

相关文章

UVa1586

【题目描述】 传送门 【题目分析】 氵 【AC代码】 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<cstdlib> #include<set> #include<map> #include<vector> …

猴子偷桃问题

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

UVa1225

【题目描述】 传送门 【题目分析】 做题做多了慢慢都忘记暴力了&#xff0c;想要快速算出来&#xff0c;找到规律&#xff0c;但是找来找去好复杂的都没有找到&#xff0c;然后写了一个不能再暴力的写法&#xff0c;就过了。。。 我还是觉得如果数据范围变成1e9那种级别的还…

linux 线程学习之条件变量

http://blog.csdn.net/hemmanhui/article/details/4417433 互斥锁&#xff1a;用来上锁。 条件变量&#xff1a;用来等待&#xff0c;当条件变量用来自动阻塞一个线程&#xff0c;直到某特殊情况发生为止。通常条件变量和互斥锁同时使用。 函数介绍&#xff1a; 1&#xff0e;…

UVa455

【题目描述】 传送门 【题目分析】 就是一个简单的暴力&#xff0c;只是需要注意输出格式比较毒瘤。 【AC代码】 #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> #include<cmath> #i…

网络相关基础概念

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

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

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

UVa227

【题目描述】 传送门 【题目分析】 题目的意思很简单&#xff0c;只是输入输出很毒瘤&#xff0c;我一开始用的fgets然后用scanf(" ")吃掉所有的空格和换行&#xff0c;可是这样有可能将迷宫的空格吃掉&#xff08;例如这个空格恰好在第一行第一列&#xff09;。 …

点对点数据链路层

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

UVa232

[题目描述] 传送门 [题目分析] 简单的模拟,注意细节 [AC代码] #include<cstdio> #include<cstring> #include<algorithm> #include<climits> #include<cctype> #include<queue> #include<set>using namespace std;typedef long…

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

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

UVa1368

[题目描述] 传送门 [题目分析] 乍一看好像有点复杂,稍微思考一下只需要找到每个位置中最多的碱基.如果相等的话优先输出字典序小的. [AC代码] #include<cstdio> #include<cstring> #include<algorithm> #include<climits> #include<cctype>…

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

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

树的相关笔试面试题

1. 树的创建 已知一个先序遍历数的结果用数组表示, 其中空节点用 null_node 表示, 要求创建出这棵树. 同样采用递归的思想, 先定义一个指针, 指向数组中的第一个元素, 然后给数组的第一个结点创建相应的结点, 然后指针后移, 递归创建根节点的左子树, 递归创建根节点的右子树, …

UVa202

[题目描述] 传送门 [题目分析] 就是一个模拟,不过稍微有点小复杂,而且输出格式有点小毒瘤. 不过只是RE了两发,PE了一发就过了,还是很开心. 需要注意数组要开很大,可能循环节出现在很后. 每个输出样例应该输出一个空行,最后面也应该有,不然会PE [AC代码] #include<cst…

linux线程同步(5)-屏障

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

浅谈软件测试

一. 什么是软件测试 软件测试是一个过程或者一系列过程, 用来测试计算机代码完成了其应该完成的功能, 不执行不该有的操作.或者说软件测试是根据软件开发各阶段的功能和说明而精心设计的一批测试用例, 并根据测试用例运行程序, 以发现程序错误的过程. 二. 软件测试的心理学和…

UVa10340

【题目描述】 传送门 【题目分析】 求字串&#xff0c;最好还是处理母串&#xff0c;每次找到一个子串就加1&#xff0c;这样处理不用处理细节 【AC代码】 #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include&l…

浅析linux下的条件变量

一.条件变量 条件变量是用来等待线程而不是上锁的&#xff0c;条件变量通常和互斥锁一起使用。条件变量之所以要和互斥锁一起使用&#xff0c;主要是因为互斥锁的一个明显的特点就是它只有两种状态&#xff1a;锁定和非锁定&#xff0c;而条件变量可以通过允许线程阻塞和等待另…

UVa1587

【题目描述】 传送门 【题目分析】 刚开始想简单了&#xff0c;认为只要相对的面相等就可以了。然后发现三个不同方向的面的边应该有相等的关系&#xff0c;即如果两个面公用一条边&#xff0c;那么这两个面的另外两条边就是另一个面的两条边。而且这三个量里面肯定有一个最…