0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

fork出的进程的父进程是从哪来的

电子设计 来源:电子设计 作者:电子设计 2020-12-24 18:41 次阅读

一、粉丝提问

fork出的进程的父进程是从哪来的?

粉丝提问,一口君必须满足

粉丝提问

二、解答

这个问题看上去很简单,但是要想把进程的父进程相关的所有知识点搞清楚,还是有点难度的,下面我们稍微拓展下,分几点来讲解这个知识点。

1. 如何查看进程ID

每个linux进程都一定有一个唯一的数字标识符,称为进程ID(process ID),进程ID总是一非负整数,它的父进程叫PPID。

查看进程ID命令:

ps -ef

查看进程

也可以使用函数来获得进程ID:

#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void); 返回:调用进程的进程ID
pid_t getppid(void); 返回:调用进程的父进程ID

2. 第一个进程init

Linux内核启动之后,会创建第一个用户级进程init,由上图可知, init 进程 (pid=1) 是除了 idle 进程 (pid=0,也就是 init_task) 之外另一个比较特殊的进程,它是 Linux 内核开始建立起进程概念时第一个通过 kernel_thread 产生的进程,其开始在内核态执行,然后通过一个系统调用,开始执行用户空间的 / sbin/init 程序。

3. fork函数

创建一个进程很简单,先来认识一下fork函数:

#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);
返回:子进程中为0,父进程中为子进程I D,出错为-1

由fork创建的新进程被称为子进程( child process)。该函数被调用一次,但返回两次,两次返回的区别是子进程的返回值是0,而父进程的返回值则是子进程的进程ID。

一般来说,在f o r k之后是父进程先执行还是子进程先执行是不确定的。这取决于内核所使用的调度算法

「举例:」

#include <unistd.h>
int main()

pid_t pid;

if ((pid = fork()) == -1) {
perror("fork");
return -1;
} else if (pid == 0) {
this is child process
printf("The return value is %d In child process!! My PID is %d, My PPID is %d", pid,getpid(), getppid());

} else {
this is parent
printf("The return value is %d In parent process!! My PID is %d, My PPID is %d", pid,getpid(), getppid());

return 0;

执行结果:

fork

由上图可知,fork被调用了一次,返回了两次。

【拓展】

使用fork函数得到的子进程是父进程的处继承了整个进程的地址空间,包括:「进程上下文、进程堆栈、内存信息、打开的文件描述符、信号控制设置、进程优先级、进程组号、当前工作目录、根目录、资源限制、控制终端」等。

fork

fork出的子进程会集成父进程的文件描述符,如果读写文件,父子进程之间会互相影响。

4. ./run 运行的程序父进程是谁?

我们来编写一个例子:

int main(int argc, const char *argv[])

while(1);
return 0;

编译执行

gcc test.c
./a.out

例子很简单,就是创建一个死循环的进程。

ps -ef 查看进程ID

执行结果

由上图可知,a.out进程的进程ID是2991,父进程ID是2675,即进程bash:

2665

bash的父进程是gnome-terminal,所以大家应该明白,我们打开1个Linux终端,其实就是启动了1个gnome-terminal进程。我们在这个终端上执行./a.out其实就是利用gnome-terminal的子进程bash通过execve()将创建的子进程装入a.out:

strace

5. 进程和终端的关系

关于进程和终端的关系可以参考以下文章:

《进程组、会话、控制终端概念,如何创建守护进程?》

6. 父进程死了,子进程怎么办?

1) 僵尸进程

僵尸进程

如上图所示,

父进程Process A创建子进程Process B,当子进程退出时会给父进程发送信号SIGCHLD;如果父进程没有调用wait等待子进程结束,退出状态丢失,转换成僵死状态,子进程会变成一个僵尸进程。

当父进程调用wait,僵尸子进程的结束状态被提取出来,子进程被删除,并且wait函数立刻返回。

实例

#include <sys/types.h>
#include <unistd.h>
create a ZOMBIE
* ps -ax | grep a.out to show the zombie

int main()

if(fork()) {
//父进程
while(1){
sleep(1);


//子进程

上述程序会保证父进程不退出,一直在while(1)中无限循环,而子进程会立刻退出。

僵尸进程

由上图可知,父进程是3096,子进程是3097,子进程因为退出后父进程没有调用wait回收子进程资源,所以子进程3097变成僵尸进程defunct。

ps -ax | grep a.out 查看进程状态

僵尸进程

2) 孤儿进程

如果父进程退出,并且没有调用wait函数,它的子进程就变成孤儿进程,会被一个特殊进程继承,这就是init进程,init 进程会自动清理所有它继承的僵尸进程。

实例代码:

#include <sys/types.h>
#include <unistd.h>

int main()

if(fork()) {
//父进程

}else{
//子进程
while(1){
sleep(1);


上述程序会保证子进程不退出,一直在while(1)中无限循环,而父进程会立刻退出。

孤儿进程:

孤儿进程

./a.out的父进程ID变成1,所以该子进程被init进程继承。

三、其他启动进程的方法

1. exec族函数

fork函数用于创建一个子进程,该子进程几乎拷贝了父进程的全部内容。exec函数族提供了一种在进程中启动另一个程序执行的方法。它可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段、代码段和堆栈段。在执行完之后,原调用进程的内容除了进程号外,其他全部都被替换了。可执行文件既可以是二进制文件,也可以是任何Linux下可执行的脚本文件。

每当进程调用一种exec函数时,该进程完全由新程序代换,而新程序从main函数开始执行。Exec并不创建新进程,所以前后进程ID也不会变。Exec只是用另一个新程序替换了当前进程的正文、数据、堆和栈段。

「何时使用?」

当进程认为自己不能再为系统和用户做出任何贡献了时就可以调用exec函数,让自己执行新的程序如果某个进程想同时执行另一个程序,它就可以调用fork函数创建子进程,然后在子进程中调用任何一个exec函数。这样看起来就好像通过执行应用程序而产生了一个新进程一样。

「函数原型」

函数原型

2. cron命令

在Linux系统中,计划任务一般是由cron承担,我们可以把cron设置为开机时自动启动。cron启动后,它会读取它的所有配置文件(全局性配置文件/etc/crontab,以及每个用户的计划任务配置文件),然后cron会根据命令和执行时间来按时来调用度工作任务。

检查cron是否安装:

ps -ef | grep cron

croncrontab -u //设定某个用户的cron服务,一般root用户在执行这个命令的时候需要此参数
crontab -l //列出某个用户cron服务的详细内容
crontab -r //删除某个用户的cron服务
crontab -e //编辑某个用户的cron服务

root查看自己的cron设置:

crontab -u root -l

或者直接看自己名下的任务:

crontab -l

创建任务:

crontab -e

打开默认编辑器编辑后保存退出即可

编辑基本格式 :

*****command
分 时 日 月 周 命令
第1列表示分钟1~59 每分钟用*或者 1表示
第2列表示小时1~23(0表示0点)
第3列表示日期1~31
第4列表示月份1~12
第5列标识号星期0~6(0表示星期天)
第6列要运行的命令
如果写为*, 表示每X
如果想定义间隔,在X后加"/"和间隔的数字

每隔一分钟打印一下系统时间

1 * * * * date >> ~/t.log //>> means append

3. at

在linux系统如果你想要让自己设计的备份程序可以自动在某个时间点开始在系统底下运行,而不需要手动来启动它,又该如何处置呢?

这些例行的工作可能又分为一次性定时工作与循环定时工作,在系统内又是哪些服务在负责?

还有,如果你想要每年在老婆的生日前一天就发出一封信件提醒自己不要忘记,linux系统下该怎么做呢?

但是crontab 主要用来提交不断循环执行的job, 而at 用来提交一段时间后执行的job(执行完就自动删除整个job)

「举例:」

1) 首先检查atd服务有无开启在一个指定的时间执行一个指定任务,只能执行一次,且需要开启atd进程

ps -ef | grep atd查看,
开启用/etc/init.d/atd start or restart;
开机即启动则需要运行 chkconfig --level 2345 atd on

2) 定时在11:30am用ls列出当前目录内容并写入~/log文件

cd ~
at 11:30am today
at>ls > ~/t.log
at> <EOT> //按Ctl-D退出

审核编辑:符乾江


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 进程
    +关注

    关注

    0

    文章

    196

    浏览量

    13909
  • Fork
    +关注

    关注

    0

    文章

    14

    浏览量

    3244
收藏 人收藏

    评论

    相关推荐

    true studio调试,只显示汇编进程不显示C进程的原因?

    true studio 调试,只显示汇编进程,不显示C进程的原因?
    发表于 04-18 06:56

    浅谈Linux的进程

    进程和程序的区别: 进程是动态的,程序是静态的 一、进程的创建(fork()函数) int main(){ pid_t pid; pid=fork
    的头像 发表于 01-28 15:54 153次阅读
    浅谈Linux的<b class='flag-5'>进程</b>

    如何查看系统是否有僵尸进程

    进程中的指令已经执行完成,但是进程PCB结构还没有回收。   即子进程先于父进程退出后,子进程的PCB需要其父
    的头像 发表于 11-29 15:52 4536次阅读
    如何查看系统是否有僵尸<b class='flag-5'>进程</b>

    Linux下进程通信的方法

    进程是操作系统的概念,每当我们执行一个程序时,对于操作系统来讲就创建了一个进程,在这个过程中,伴随着资源的分配和释放。可以认为进程是一个程序的一次执行过程。
    的头像 发表于 11-29 14:45 456次阅读
    Linux下<b class='flag-5'>进程</b>通信的方法

    进程响应时间是指什么

    进程响应时间是指从发出请求到收到响应的时间间隔,是衡量系统性能和用户体验的重要指标之一。在计算机系统中,进程是指一个正在运行的程序实例。当用户发出请求,系统会创建一个新的进程来处理该请求。进程
    的头像 发表于 11-17 11:31 623次阅读

    进程通信的应用场景

    进程的概念 进程是操作系统的概念,每当我们执行一个程序时,对于操作系统来讲就创建了一个进程,在这个过程中,伴随着资源的分配和释放。可以认为进程是一个程序的一次执行过程。
    的头像 发表于 11-11 14:42 427次阅读
    <b class='flag-5'>进程</b>通信的应用场景

    进程间通信的原理

    一.为什么进程间需要通信? 1).数据传输 一个进程需要将它的数据发送给另一个进程; 2).资源共享 多个进程之间共享同样的资源; 3).通知事件 一个
    的头像 发表于 11-10 17:05 547次阅读
    <b class='flag-5'>进程</b>间通信的原理

    什么是进程

    在探讨这个问题之前,我们先来弄清什么是进程进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。程序是指令、数据及其
    的头像 发表于 11-08 15:21 2413次阅读
    什么是<b class='flag-5'>进程</b>

    DNS的各种玩法:程序编译到进程的过程解析

    在Linux中使用fork创建进程,返回进程id。通过id的不同让父子进程各干其事,然后使用execvp执行具体任务
    发表于 10-20 11:10 225次阅读
    DNS的各种玩法:程序编译到<b class='flag-5'>进程</b>的过程解析

    常见的进程间通信方式

    进程间通信 如果两个进程,想要知道对方在干嘛,或者进行协调运行,就需要进程间通信。下面介绍一下常见的进程间通信方式。 无名管道: 管道是一种半双工的通信方式。数据只能单向流动,而且只能
    的头像 发表于 10-08 15:48 1002次阅读
    常见的<b class='flag-5'>进程</b>间通信方式

    为什么需要进程 特征和定义有哪些

    为什么需要进程 通常程序不能并发执行,因为程序并发执行的结果,是不可再现的。为了使程序,可以并发执行,且能对其加以描述和控制,引入了进程的概念。 进程的特征和定义 进程是程序的一次执行
    的头像 发表于 10-08 15:29 439次阅读
    为什么需要<b class='flag-5'>进程</b> 特征和定义有哪些

    如何SD卡读取bin文件数据来执行IAP进程

    应用程序 : 此代码显示如何执行 IAP 进程, SD 卡读取 bin 文件数据以更新用户应用程序 。 BSP 版本: NUC230/240系列 BSP CMSIS V3.01.001 硬件
    发表于 08-22 07:21

    Linux下进程相关知识

    进程是在你的系统上运行的程序。它们由内核管理,每个进程都有一个与之关联的ID,称为进程ID(PID)。这个PID是按照进程创建的顺序分配的。
    发表于 08-09 10:02 233次阅读
    Linux下<b class='flag-5'>进程</b>相关知识

    进程有哪些状态?细说进程的状态

    进程有哪些状态?这个问题在面试的时候出现的概率也比较高。
    的头像 发表于 07-25 17:06 1024次阅读
    <b class='flag-5'>进程</b>有哪些状态?细说<b class='flag-5'>进程</b>的状态

    进程间通信的机制有哪些

    进程间通信(interprocess communication,简称IPC)指两个进程之间的通信。系统中的每一个进程都有各自的地址空间,并且相互独立、隔离,每个进程都处于自己的地址空
    的头像 发表于 07-21 11:23 741次阅读
    <b class='flag-5'>进程</b>间通信的机制有哪些