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

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

3天内不再提示

你们知道Linux的进程是怎样创建的吗

Linux爱好者 来源:CS指南 作者:大白 2021-11-09 10:46 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

Linux的进程是怎样创建的

Linux系统创建进程都是由已存在的进程创建的(除了0号进程),被创建的进程叫做子进程,创建子进程的进程就做父进程。这句话是不是有点熟悉,没错,Linux进程串起来也是一颗树的结构。就像下面这样:

01d5842e-3f30-11ec-9195-dac502259ad0.png

在Linux中,为了创建一个子进程,父进程用系统调用fork来创建子进程。fork()其实就是把父进程复制了一份(子进程有自己的特性,比如标识、状态、数据空间等;子进程和父进程共同使用程序代码、共用时间片等)。

可以看下面这段代码:

#include
#include

int main()
{
int p_num = 0;
int c_num = 0;
int pid = fork();
if(pid == 0) //返回的pid为0为子进程
{
c_num++;
}
else
{
p_num++; //返回的pid大于0为父进程
}
printf("p_num=%d, c_num=%d
",p_num,c_num);
printf("pid=%d
",pid);
return 0;
}
//运行结果如下所示
p_num=1, c_num=0
pid=36101
p_num=0, c_num=1
pid=0

大家看,代码中调用了fork以后,之后的程序被执行了两遍。子进程和父进程各自的变量互相没有受到干扰。不过子进程和父进程执行的是相同的代码,子进程和父进程资源占用情况如下图所示:

02068b78-3f30-11ec-9195-dac502259ad0.png

大家可以看出,通过fork后,子进程并没有和父进程独立开,用的是相同的代码。另外还有一个问题时,这个时候子进程的时间片是和父进程一分为二来共享的。这样我创建子进程还有什么意义?为了彻底将父进程和子进程分离开来,就要用到一个系统调用 execv()。

看下面这段代码:

//process.c
#include
#include

int main()
{
int pid = fork();
if(pid == 0)
{
execv("./test.o",NULL);  //test.o是一个经过编译的c语言文件,这里记得要放test.o的绝对路径
}
printf("This is parent process
");
return 0;
}

//test.c
#include
int main()
{
printf("This is child process");
return 0;
}

//运行结果如下所示
This is parent process
This is child process

通过上面的代码可以看出,从系统调用 execv() 后,子进程直接走自己的代码了,没有像前一段代码一样把后面的代码执行了两次。通过调用 execv(),子进程和父进程就基本分离开了。

结合系统继续看Linux的进程树是什么样的

好了,通过上面的介绍,大家应该对进程是怎么创建的有一定的了解。想继续学习的我们来接着上强度。

我们在 Linux 系统上通过 ps - ef 命令查看系统目前的进程:

/[root@localhost lucas]# ps -ef
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  3 21:41 ?        00:02:38 /usr/lib/systemd/systemd --s
root           2       0  0 21:41 ?        00:00:07 [kthreadd]
root           3       2  0 21:41 ?        00:00:00 [rcu_gp]
root           4       2  0 21:41 ?        00:00:00 [rcu_par_gp]
...
rtkit       1151       1  0 21:41 ?        00:00:14 /usr/libexec/rtkit-daemon
root        1152       1  0 21:41 ?        00:00:00 /usr/sbin/ModemManager
avahi       1155       1  0 21:41 ?        00:00:06 avahi-daemon: running [linux
root        1159       1  0 21:41 ?        00:00:02 /usr/lib/systemd/systemd-mac

我来解释上表是什么意思。

首先,每一个进程都要所属一个用户,UID 就是用户的标识符(通过 root 用户创建的进程 UID 就是 root,如果我自己创建的话就应该是我的用户名,比如我的名字 "dabai")。

其次每一个进程都要有一个 ID 来表示这个进程,PID 就表示的是当前进程的 id。

最后,上文提到除了 0 号进程,每一个进程都是由他的父进程创建的,PPID 就表示当前进程的父进程 id。

通过 0 号进程创建 1 号进程和 2 号进程,然后通过 1 号进程去创建用户态进程,再通过 2 号进程创建内核态进程,就生成了 Linux 进程树。

0248cfec-3f30-11ec-9195-dac502259ad0.png

「什么是0号进程、1号进程以及2号进程?」

0号进程:在内核初始化的过程中,会先通过指令 struct task_struct init_task = INIT_TASK(init_task) 创建 0 号进程。这是唯一一个没有通过 fork 或者 kernel_thread 产生的进程。是进程列表的第一个。但是这个进程不是实际意义上的进程,类似与链表头。所以虽然 0 号进程是在内核态创建的,但不能说 0 号进程是内核态的第一个进程,反而要说 2 号进程是内核态的第一个进程。

1号进程:通过调用指令 kernel_thread(kernel_init, NULL, CLONE_FS) 从内核态切换到用户态来创建的,1号进程是所有用户态的祖先。

2号进程:通过调用指令 kernel_thread(kthreadd, NULL, ClONE_FS | CLONE_FILES) 来创建,2号进程负责所有内核态的进程的调度和管理,是内核态所有进程的祖先。(注意,内核态不区分线程和进程,所以说进程和线程都可以,都是任务)

「为什么要先创建 0 号进程,而不直接创建 1 号进程?」

现在对于为什么要先创建 0 号进程而不直接创建1号和2号进程有许多讨论。我认为...算了,我不认为了,一展开讲这篇文章又收不了尾了,以后可以专门写一篇文章来论述这里。简单来说就是Linux 的第一个进程不适合是一个真进程,需要一个没有数据之类东西的假进程。

「为什么要区分用户态和内核态?」

因为有了多个进程,对于关键资源来说,就会产生争用以及误操作破坏资源等情况。这时就需要对资源的访问权限进行一定的限制。x86 提供了分层的权限机制,内核态具有最高的访问权限,而用户态访问核心资源时必须要切换到内核态才可以访问。

好了,我看了下字数,这篇文章已经不少了,接下来我还会继续去分享进程和线程的更多细节,也会根据读者的反馈在已完成的文章上不断完善,欢迎大家持续关注呀!

参考资料:

【1】Linux进程的创建与管理:https://blog.csdn.net/qq_38410730/article/details/81193118

【2】极客时间:《趣谈Linux操作系统

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

    关注

    88

    文章

    11628

    浏览量

    217970
  • PID
    PID
    +关注

    关注

    37

    文章

    1489

    浏览量

    90083
  • 代码
    +关注

    关注

    30

    文章

    4941

    浏览量

    73148

原文标题:Linux 的进程是怎样创建的

文章出处:【微信号:LinuxHub,微信公众号:Linux爱好者】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Linux多线程对比单线程的优势

    Linux系统中,线程是操作系统能够进行运算调度的最小单位。线程被包含在进程之中,是进程中的实际运行单位。一个进程可以拥有多个线程,这些线程共享相同的内存空间和系统资源。线程主要解决
    发表于 12-01 06:11

    大神们,想知道你们都用什么ide编程调试器? Arduino IDE?还是 e2studio ?还有其他吗?哪个好用呢

    大神们,想知道你们都用什么ide编程调试器? Arduino IDE? 还是 e2studio ? 还有其他吗? 哪个IDE好用呢? 求指点呀
    发表于 11-30 12:05

    Linux进程间通信(IPC)全解析:从管道到 Socket,一篇讲透

    在 Linux 世界里,进程并非孤立存在。无论是后台服务协作(如 Web 服务器与数据库)、命令行工具联动(如ps | grep),还是复杂应用的模块通信,都离不开 进程间通信(IPC
    的头像 发表于 11-14 21:38 1.2w次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>进程</b>间通信(IPC)全解析:从管道到 Socket,一篇讲透

    知道板卡厂商参与芯片研发的α阶段意味着什么?

    大家都知道芯片很重要,但你是否知道一颗芯片从设计构思到最终量产,需要经历怎样一个漫长的过程吗?
    的头像 发表于 09-24 17:08 7263次阅读
    你<b class='flag-5'>知道</b>板卡厂商参与芯片研发的α阶段意味着什么?

    【HZ-T536开发板免费体验】—— linux创建线程

    任务,并行是多个处理器或多核处理器同时执行不同的任务。 Linux系统中进行多线程编程时,会涉及到主线程和子线程的操作: 1)主线程是程序的执行入口,它是程序中第一个创建的线程。 2)子线程,是主线
    发表于 09-01 21:31

    【HZ-T536开发板免费体验】—— linux 进程创建

    Linux进程通信方式有这几种: 1。管道 2。信号量 3。消息队列 4。共享内存 在本帖子中,我会讲解fork(),exit()系统调用的实践。通过应用编程来实现系统调用。 1,进程创建
    发表于 09-01 20:49

    Linux权限体系解析

    你真的了解Linux权限吗?大多数人只知道rwx,但Linux的权限体系远比你想象的复杂和强大。今天我们深入探讨Linux的12位权限体系,这是每个运维工程师都应该掌握的核心知识。
    的头像 发表于 07-23 16:57 592次阅读

    Linux常用命令大全

    Linux常用命令是指在Linux操作系统中广泛使用的命令工具,这些命令工具可以完成各种不同的任务,如管理文件和目录、操作进程、网络通信、软件安装等。
    的头像 发表于 05-03 18:08 1612次阅读

    Linux后台进程管理详解

    当我们在终端或控制台工作时,可能不希望由于运行一个作业而占住了屏幕,因为可能还有更重要的事情要做,比如阅读电子邮件。对于密集访问磁盘的进程,我们更希望它能够在每天的非负荷高峰时间段运行(例如凌晨)。为了使这些进程能够在后台运行,也就是说不在终端屏幕上运行,有几种选择方法可
    的头像 发表于 04-25 11:04 801次阅读
    <b class='flag-5'>Linux</b>后台<b class='flag-5'>进程</b>管理详解

    Linux系统进程管理入门指南

    Linux 系统中,进程是正在运行的程序的实例。理解进程的管理、查看和控制对于系统管理员和开发者来说非常重要
    的头像 发表于 04-22 14:34 857次阅读
    <b class='flag-5'>Linux</b>系统<b class='flag-5'>进程</b>管理入门指南

    Linux进程状态详解

    进程状态是task_struct内的一个整数;进行:进程在调度队列中,进程的状态都是running,阻塞:等待某种设备或者资源就绪。进程是一个队列,设备也是一个队列,当我们读磁盘,读网
    的头像 发表于 04-01 09:46 809次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>进程</b>状态详解

    hyper-v 备份,hyper-v怎样进行虚拟机的创建

    虚拟机技术打破了传统计算机的限制,为我们带来了全新的计算机模式。今天给大家介绍hyper-v怎样进行虚拟机的创建?    hyper-v怎样进行虚拟机的创建?    使用PowerSh
    的头像 发表于 02-05 14:54 797次阅读
    hyper-v 备份,hyper-v<b class='flag-5'>怎样</b>进行虚拟机的<b class='flag-5'>创建</b>

    Linux中的用户与创建

    Linux中的用户与创建 用户的类型 超级管理用户: 权限最高的用户(uid:0) #uid:是用户的身份证号,Linux系统只认uid 普通用户: 权限受限的用户(uid:1000-60000
    的头像 发表于 12-20 14:24 1199次阅读
    <b class='flag-5'>Linux</b>中的用户与<b class='flag-5'>创建</b>

    深入解析Linux程序与进程

    关于某个数据集合的一次运行活动。作为系统进行资源分配和调度的基本单位,是操作系统结构的基础。 程序与进程的关系 进程的状态 基础进程状态 创建状态:
    的头像 发表于 12-18 11:01 838次阅读
    深入解析<b class='flag-5'>Linux</b>程序与<b class='flag-5'>进程</b>

    Hyper-V创建虚拟机配置IP等网络配置原理(Linux、Windows为例)

    大家知道Windows系统里面内置了Hyper-V管理器,用来创建和管理本地虚拟机环境。今天我创建了两台虚拟机,一台是CentOS7.9(Linux),另一台是Windows 11,然
    的头像 发表于 12-09 10:24 5583次阅读
    Hyper-V<b class='flag-5'>创建</b>虚拟机配置IP等网络配置原理(<b class='flag-5'>Linux</b>、Windows为例)