守护进程,也就是通常所说的Daemon进程,是Linux中的后台服务进程。周期性的执行某种任务或等待处理某些发生的事件。
Linux系统有很多守护进程,大多数服务都是用守护进程实现的。比如:像我们的tftp,samba,nfs等相关服务。
UNIX的守护进程一般都命名为*d的形式,如httpd,telnetd等等。
守护进程会长时间运行,常常在系统启动时就开始运行,直到系统关闭时才终止。
从终端开始运行的进程都会依附于这个终端,这个终端称为这些进程的控制终端。当控制终端被关闭时,相应的进程都会被自动关闭。咱们平常写进程时,一个死循环程序,咱们不知道有ctrl+c的时候,怎么关闭它呀,是不是关闭终端呀。也就是说关闭终端的同时也关闭了我们的程序,但是对于守护进程来说,其生命周期守护需要突破这种限制,它从开始运行,直到整个系统关闭才会退出,所以守护进程不能依赖于终端。
ps axj
a: 显示所有
x:显示没有控制终端的进程
j:显示与作业有关的信息(显示的列):会话期ID(SID),进程组ID(PGID),控制终端(TT),终端进程组ID(TRGID)
• 所有的守护进程都是以超级用户启动的(UID为0);
• 没有控制终端(TTY为?);
• 终端进程组ID为-1(TPGID表示终端进程组ID,该值表示与控制终端相关的前台进程组,如果未和任何终端相关,其值为-1;
• 所有的守护进程的父进程:
历史上,Linux 的启动一直采用init进程;下面的命令用来启动服务。
这种方法有两个缺点:
1. 启动时间长。init进程是串行启动,只有前一个进程启动完,才会启动下一个进程。
2. 启动脚本复杂。init进程只是执行启动脚本,不管其他事情。脚本需要自己处理各种情况,
这往往使得脚本变得很长。
Systemd
就是为了解决这些问题而诞生的。它的设计目标是,为系统的启动和管理提供一套完整的解决方案。
根据 Linux 惯例,字母d是守护进程(daemon)的缩写。Systemd 这个名字的含义,就是它要守护整个系统。
shell里的每个进程都属于一个进程组,创建进程组的目的是用于简化向组内所有进程发送信号的操作,即如果一个信号是发给一个进程组,则这个组内的所有进程都会受到该信号【方便管理】。
进程组内的所有进程都有相同的PGID,等于该组组长的PID。(进程组组长:进程组中有一个进程担当组长。进程组ID(PGID)等于进程组组长的进程ID。已知一个进程,要得到该进程所属的进程组ID可以调用getpgrp。一个进程可以通过另一个系统调用setpgrp来加入一个已经存在的进程组或者创建一个新的进程组。
如果内核支持_POSIX_JOB_CONTROL(该宏被定义)则内核会为Shell 上的每一条命令行(可能由多个命令通过管道等连接)创建一个进程组。从这点上看,进程组不是进程的概念,而是shell上才有,所以在task_struct里并没有存储进程组id之类的变量。
进程组的生命周期到组中最后一个进程终止或其加入其他进程组(离开本进程组)为止。
一般一个用户登录后新建一个会话,每个会话也有一个ID来标识(SID)。登录后的第一个进程叫做会话领头进程(session leader),通常是一个shell/bash。对于会话领头进程,其PID=SID。
一个会话一般会拥有一个控制终端用于执行IO操作。会话的领头进程打开一个终端之后, 该终端就成为该会话的控制终端。与控制终端建立连接的会话领头进程也称为控制进程 (controlling process) 。一个会话只能有一个控制终端。
该进程组中的进程能够向终端设备进行读、写操作的进程组。例如登陆shell(例如bash)通过调用int tcsetpgrp(int fd, pid_t pgrp); 函数设置为某个进程组pgrp关联终端设备fd,该函数执行成功后,该进程组pgrp成为前台进程组。
该进程组中的进程只能够向终端设备写。
每个进程还有一个属性,终端进程组ID(TPGID),用来标识一个进程是否处于一个和终端相关的进程组中。前台进程组中的进程的TPGID=PGID,后台进程组的PGID≠TPGID。若该进程和任何终端无关,其值为-1。通过比较他们来判断一个进程是属于前台进程组,还是后台进程组。
进程组、对话期和控制终端关系
1 . 打开第一个终端执行命令:
ping 127.0.0.1 -aq | grep icmp & // 通过管道将两个命令串接起来ping –q不显示timeout信息,将其设置到后台并running
2 . 在第一个终端继续执行命令,在前台再新建一个进程组。【注意没有&】
ping 127.0.0.1 -aq | grep icmp //在前台再新建一个进程组,
3 . 开启第二个终端并运行
ps axj | grep pts/0 即过滤只看pts/0里的会话
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
2109 2111 2111 2111 pts/0 2538 Ss 1000 0:01 bash
2111 2503 2503 2111 pts/0 2538 S 1000 0:00 ping 127.0.0.1 -aq
2111 2504 2503 2111 pts/0 2538 S 1000 0:00 grep --color=auto icmp
2111 2538 2538 2111 pts/0 2538 S+ 1000 0:00 ping 127.0.0.2 -aq
2111 2539 2538 2111 pts/0 2538 S+ 1000 0:00 grep --color=auto timeo
• SID都是2111,说明大家都在一个Session里
• 有三个进程组PGID 2111,2503和2538。我们可以看到用|连起来的ping和grep是在一个进程组里的。
• 2538这个进程组是一个前台的进程组,因为其PGID==TGPID, 2503这个进程组是一个后台进程组
4 . 在第一个终端中执行Ctrl+C
5 . 在第二个终端里继续ps axj | grep pts/0
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
2109 2111 2111 2111 pts/0 2111 Ss+ 1000 0:01 bash
2111 2503 2503 2111 pts/0 2111 S 1000 0:00 ping 127.0.0.1 -aq
2111 2504 2503 2111 pts/0 2111 S 1000 0:00 grep --color=auto icmp
• 2538那个前台进程组的所有进程都消失了,说明信号会发给前台进程组的所有进程
• 2111,即bash所在的那个进程组成为了前台进程组。
守护进程创建流程如下:
1. 创建子进程,父进程退出
2. 在子进程中创建新会话
3. 改变当前目录为根目录
4. 重设文件权限掩码
5. 关闭文件描述符
由于守护进程是脱离控制终端的,因此,完成第一步后就会在shell终端里造成一程序已经运行完毕的假象。之后的所有后续工作都在子进程中完成,而用户在shell终端里则可以执行其他的命令,从而在形式上做到了与控制终端的脱离。
由于父进程已经先于子进程退出,会造成子进程没有父进程,从而变成一个孤儿进程。在Linux中,每当系统发现一个孤儿进程,就会自动由1号进程收养。原先的子进程就会变成init进程的子进程。
setsid()函数的作用。一个进程调用setsid()函数后,会发生如下事件:
• 首先内核会创建一个新的会话,并让该进程成为该会话的leader进程,
• 同时伴随该session的建立,一个新的进程组也会被创建,同时该进程成为该进程组的组长。
• 该进程此时还没有和任何控制终端关联。若需要则要另外调用tcsetpgrp,前面讲前台进程组时介绍过。
调用setsid()有以下3个作用:
• 让进程摆脱原会话的控制。
• 让进程摆脱原进程组的控制。
• 让进程摆脱原控制终端的控制。
那么,在创建守护进程时为什么要调用setsid()函数呢?
读者可以回忆一下创建守护进程的第一步,在那里调用了fork()函数来创建子进程再令父进程退出。由于在调用fork()函数时,子进程全盘复制了父进程的会话期、进程组和控制终端等,虽然父进程退出了,但原先的会话期、进程组和控制终端等并没有改变,因此,还不是真正意义上的独立。而setsid()函数能够使进程完全独立出来,从而脱离所有其他进程和终端的控制。
详细见man 2 setsid。
这一步也是必要的步骤。使用fork()创建的子进程继承了父进程的当前工作目录。
由于在进程运行过程中,当前目录所在的文件系统(如“/mnt/usb”等)是不能卸载的,这对以后的使用会造成诸多的麻烦(如系统由于某种原因要进入单用户模式)。
因此,通常的做法是让“/”作为守护进程的当前工作目录,这样就可以避免上述问题。当然,如有特殊需要,也可以把当前工作目录换成其他的路径,如/tmp。改变工作目录的常见函数是chdir()。
文件权限掩码是指屏蔽掉文件权限中的对应位。
例如,有一个文件权限掩码是050,它就屏蔽了文件组拥有者的可读与可执行权限。由于使用fork()函数新建的子进程继承了父进程的文件权限掩码,这就给该子进程使用文件带来了诸多的麻烦。
因此,把文件权限掩码设置为0,可以大大增强该守护进程的灵活性。设置文件权限掩码的函数是umask()。在这里,通常的使用方法为umask(0)。即赋予最大的能力。
同文件权限掩码一样,用fork()函数新建的子进程会从父进程那里继承一些已经打开的文件。这些被打开的文件可能永远不会被守护进程读或写,但它们一样消耗系统资源,而且可能导致所在的文件系统无法被卸载。
在上面的第(2)步之后,守护进程已经与所属的控制终端失去了联系,因此,从终端输入的字符不可能达到守护进程,守护进程中用常规方法(如printf())输出的字符也不可能在终端上显示出来。
所以,文件描述符为0、1和2的3个文件(常说的输入、输出和报错这3个文件)已经失去了存在的价值,也应被关闭。
/*
关注一口Linux
*/
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main()
{
pid_t pid;
int i, fd;
char *buf = "This is a Daemon\n";
pid = fork();
if (pid < 0) {
printf("Error fork\n");
exit(1);
}
/* 第一步,父进程退出 */
if (pid > 0) {
exit(0);
}
/* 第二步 */
setsid();
/* 第三步 */
chdir("/");
/* 第四步 */
umask(0);
/* 第五步 */
for(i = 0; i < getdtablesize(); i++)
{
close(i);
}
/* 这时创建完守护进程,以下开始正式进入守护进程实际工作
* 注意:由于此时守护进程完全脱离了控制终端,因此,不能像其他普通进程
* 一样通过printf或者perror将错误信息输出到控制终端,一种通用的办
* 法是使用syslog服务,将程序中的出错信息输入到系统日志文件中。
* 本程序着重演示创建守护进程的步骤,暂不演示syslog。
*/
while(1) {
if ((fd = open("/tmp/daemon.log",
O_CREAT|O_WRONLY|O_APPEND, 0600)) < 0) {
exit(1);
}
write(fd, buf, strlen(buf) + 1);
close(fd);
sleep(10);
}
exit(0);
}
执行结果 由上图可见:• 守护进程./run 的UID为0;• 没有控制终端(TTY为?);• 终端进程组ID为-1;• 守护进程的父进程为1516,即systemd。
本文由哈喽比特于2年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/NSB96Rx9AxclGzc_pat2SA
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。