物联网和linux的关系,物联网学习进程——Linux进程间关系和守护进程1

本文详细介绍了Linux进程间的交互机制,包括进程组的概念、父进程与子进程的关系,以及守护进程的创建与特点。通过实例演示了进程组如何影响控制台操作,以及守护进程如何独立运行后台任务。适合深入理解Linux进程管理的读者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

物联网学习进程——Linux进程间关系和守护进程

一、实验说明

1.回顾

上一节课我们已经学习了Linux系统编程之进程控制。今天让我们来学习Linux进程间关系和守护进程。

2. 环境介绍

本实验环境采用带桌面的Ubuntu Linux环境,实验中会用到桌面上的程序:

LX终端(LXTerminal): Linux命令行终端,打开后会进入Bash环境,可以使用Linux命令。常用Linux命令大全

gedit:非常好用的编辑器.gedit使用方法

GVim:非常好用的编辑器,最简单的用法可以参考课程Vim使用方法

3. 环境使用

#首先点击“开始试验”

52c85d6c4a28ed5e74b08d39198f386f.png

开始实验后,按照实验步骤在环境中进行操作,每完成一步点击底部的 下一步;学习过程中可以将心得收获记录在页面上方的 实验报告,遇到问题可以直接点击页面上方 我要提问 进行提问。实验操作界面包含两栏,左边栏为实验步骤、实验报告,右边栏为虚拟机环境(部分课程是 Web IDE 或 Jupyter Notebook)和工具栏。

99a571c5b46210a06fe0a7cf7e807506.png

右边栏工具栏中有很多实验中可能用到的功能,可以点击一一尝试:

4bf09954221963c66cd3739881503635.png

使用GVim编辑器输入实验所需的代码及文件,使用LX终端(LXTerminal)运行所需命令进行操作。

此处输入链接的描述

实验报告页面可以在“我的主页”中查看,其中含有每次实验的截图及笔记,以及实验的有效学习时间(指的是在实验桌面内操作的时间,如果没有操作,系统会记录为发呆时间),这些都是您学习的真实性证明。

二、实验过程

2.1进程组

实验原理

每个进程除了有一个进程ID外,还属于一个进程组。进程组是一个或多个进程的集合。通常,他们与同一个作业相关联,他们可以接受来自于同一个终端的信号。每个进程组有一个唯一的组ID,每个进程组都可以有一个组长进程,进程组ID就是组长的ID。组长进程可以创建一个进程组,创建该组中的进程,然后终止。只要在某个进程组中一个进程存在,该进程组就存在,这与组长进程是否终止无关。

将组长进程杀死后查看,发现进程组并没有被影响到,这也印证了我们上面的说法,组长进程存在与否不影响进程组。

作业

Shell分前后台来控制的不是进程而是zuoye(Job)或者进程组(Process Group)。一个前台作业可以由多个进程组成,一个后台也可以由多个进程组成,Shell可以运行一个前台作业和多个后台作业,这称为作业控制。

作业与进程组的区别:如果作业中的某个进程创建出了一个子进程,则子进程不属于作业。

一旦作业运行结束,Shell就把自己提到前台(子进程还在,但它不属于作业),如果原来的前台进程还存在(如果这个子进程还没终止),它自己变为后台进程组。

接下来我们编写源代码说明父进程退出后,子进程还在运行。

创建代码文件

#include

#include

int main()

{

pid_t id = fork();

if(id<0)

perror("fork\n");

else if(id==0)

{ while(1){

printf("I am child(%d),i am running...\n",getpid());

sleep(4);}}

else

{

int i = 5;

printf("I am father(%d),i am going to dead...%d\n",getpid(),i--);

sleep(4);

}

return 0;

}

保存为2.cpp ,在终端输入 g++ 2.cpp -o 2.out

然后我们在 Xfce 终端输入 ./2.out

思考

当这段代码运行起来后,为什么我们可以发现5s之内shell无法接受任何指令?

2.2守护进程实验原理

实验原理

守护进程也称精灵进程(Daemon),是运行在后台的一种特殊进程。它独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件,守护进程是一种很有用的进程。Linux大多数服务器就是用守护进程实现的。比如:ftp服务器,ssh服务器,Web服务器httpd等。同时,守护进程完成很多系统任务,比如,作业规划进程crond等。

Linux系统启动时会启动很多系统服务进程,这些系统服务进程没有控制终端,不能直接和用户交互。其它进程都是在用户登录或运行时创建的,在用户结束或注销时终止,但系统服务进程不受用户登录的影响,它一直运行着,这种进程被称为守护进程。

创建守护进程

创建守护进程最关键的一步是调用setsid函数创建一个新的Session,并成为Session Leader。

pid_t setsid(void);

该函数调用成功时返回新创建的Session的ID,出错返回-1,调用此函数之前,当前进程不允许是进程组的Leader。为了保证函数不出错,我们利用fork函数创建一个子进程,在子进程中调用它就可以了。

成功调用该函数后:

创建一个新的Session,当前进程成为Session Leader,当前进程的id就是Session的id。

创建一个新的进程组,当前进程成为进程组的Leader,当前进程的id就是进程组的id。

如果当前进程原本有一个控制终端,则它失去这个控制终端,成为一个没有控制终端的进程。

编写源代码

#include

#include

#include

#include

#include

#include

#include

void mydaemon()

{

umask(0);

pid_t n = fork();

if(n<0)

perror("fork\n");

else if(n>0)

exit(1);

pid_t m = setsid();

printf("sid = %d\n",m); //打印出守护进程的ID

chdir("/"); //重定向到根目录

close(0); //关闭不需要的文件描述符

close(1);

close(2);

signal(SIGCHLD,SIG_IGN);

}

int main()

{

mydaemon();

while(1){}

return 0;

}

思考:

保存为3.cpp ,在终端输入 g++ 3.cpp -o 3.out 后

多次运行./3.out结果如何?如何直接调用daemon函数来创建一个守护进程?

三、实验结果(每个例子都要有源代码和效果图,有调试图)

2.1 原代码

#include

#include

int main()

{

pid_t id = fork();

if(id<0)

perror("fork\n");

else if(id==0)

{ while(1){

printf("I am child(%d),i am running...\n",getpid());

sleep(4);}}

else

{

int i = 5;

printf("I am father(%d),i am going to dead...%d\n",getpid(),i--);

sleep(4);

}

return 0;

}

2.1 截图

663220f414799eb6d0b6ce80b49dddec.png

ad332b83ad00a46c8eea85210d1c6db0.png

9af98aab8061e2c742c067e143145267.png

2.1 结论分析

通过实验结果截图得知,线程组创建之后5s内无法操作shell,当进程组长消亡后,组员(子线程)会一直运行在系统后台,如果没有相关操作,会一直运行下去,打印 i am child(281),i am running...的语句,直达内存完全占有用,停止打印。可见组长的生命周期不会影响到组员的生命周期。

2.2 原代码

#include

#include

#include

#include

#include

#include

#include

void mydaemon()

{

umask(0);

pid_t n = fork();

if(n<0)

perror("fork\n");

else if(n>0)

exit(1);

pid_t m = setsid();

printf("sid = %d\n",m); //打印出守护进程的ID

chdir("/"); //重定向到根目录

close(0); //关闭不需要的文件描述符

close(1);

close(2);

signal(SIGCHLD,SIG_IGN);

}

int main()

{

mydaemon();

while(1){}

return 0;

}

2.2 截图

56bdfcc94bef6966a35cf8b8badb8b25.png

90e2bc3c7d0ee5da937e8854361ff44b.png

2.2 结论分析

根据实验结果截图分析,第一次运行打印sid为351,多次运行后,每次打印的sid否都有不同,可见pid_t setsid(void)成功调用后,创建一个新的Session,当前进程成为Session Leader,当前进程的id就是Session的id。 创建一个新的进程组,当前进程成为进程组的Leader,当前进程的id就是进程组的id。 如果当前进程原本有一个控制终端,则它失去这个控制终端,成为一个没有控制终端的进程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值