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

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

3天内不再提示

基于Linux进程管理的详细剖析

Q4MP_gh_c472c21 2018-01-26 11:24 次阅读

上一篇嵌入式未来一段时间还是Linux天下,一位嵌入式er初探Linux kernel经验,我们讲到了Linux内核开发和应用程序开发,今天我们来讲讲Linux重点部分Linux的进程管理。

OS是干啥的?处理提供对硬件层的抽象以外,还担负着很多的硬件管理功能,而这些功能,用一句话来说,就是来处理各个部件的时空复用问题(时间和空间的重用问题,如cpu是分时重用的(当然还有多核cpu的特例,而内存是即分时又分空的……)。

往古至今,大牛们对OS的定义不下其数,而本人认为最有说服力的OS的定义就是:“所有软件(特指应用程序)的交集”,料想计算机诞生初期都是专用机,在一款机器上只能跑订制的专用程序,而这个程序要自己做好所有硬件的协调且还要完成他应有的本分工作,慢慢的计算机向通用型发展,为了提高系统利用率和避免盲目且重复的底层实现,OS随着需求一步步形成且不断完善……

不知你发现没有,好多东西都是在历史舞台上重复出现的,仿佛对应着“20年后又是一条好汉”这句话,看现在的google的Chrome OS,其实最初的原型说白了就是把chrome浏览器必要的底层重新从OS中剥离,使其具有独立运行的能力,这不是有点最早的专用机的味道,计算机这东西很是神奇,一个好的点子就可能改变整个市场,甚至一个世纪……

扯远了,重新回来,回到复用性说起吧,因为cpu要跑的程序很多,但是cup个数有限,这就牵扯到cpu的重用,也就是被多个进程重用(进程与程序的区别就不多说了,自己熟悉OS知识去吧,简单的提一下程序运行的本质就是从内核申请个进程,再把程序包中的代码拷贝到对应进程的代码域并设置好相关变量数据令进程跑起来,所以程序只是静态的代码,而进程是一个不断从程序加载代码的执行过程),这是由于进程间要复用cpu,所以就要求有人来负责他们有组织有纪律的复用,并协调进程间的轻重缓急、切换规则、切换后的一些处理……

另外还有怎样生产进程、怎样切换、怎样销毁……这些由谁完成?当然是OS,对于linux,当然是kernel了。毕竟OS就是用来跑程序的,而进程就是程序的灵魂,可见进程管理的重要性,咱就从进程说起先。

虽然吧,进程是处于执行期的程序,但是要明白,进程并不仅仅局限于一段可执行的代码,你想,要想跑进程,你得知道是谁的进程,要区别于其他进程;还要保证当前进程不能随意访问其他进程的地址空间,要是连这都不限制,那写个黑客程序多随意啊;还牵扯到多线程问题;另外,由于进程间是复用cpu的,就是一会儿这个执行,一会儿换另一个,那你还要保证它可以接着上次的执行啊,要不不就乱了套了……如此说来,进程需要的东西大概有:

打开的文件

挂起的信号 (linux一个事件的处发是基于信号机制的,就像windows的事件机制)

内核内部数据 (这就是传说中恢复现场用的,要还原到进程切换前的状态需要保存现场)

处理器状态 (没理解错的话,这也是现场保持的一部分,因为有些程序的执行是)

地址空间

一个或多个执行线程(Linux下的线程实现非常有趣,也非常简单,本质上也就是几个共享进程,没有设置专门的线程数据结构)

以上是Linux下进程的主要组成部分,当然了,进程管理么,有了进程还要有管理,管理相关着进程的策略和生命周期等一些东西,我们会慢慢讲来。

话说很久很久以前,进程自创建时刻起就开始存活了,活在Linux世界的进程爹fork()系统调用一下,就会生个小进程,比和女儿国的水来的还快。进程这东西没耳朵没眼睛的,他爹咋知道啥时候生好了。既然fork()是生婆,那这是生婆最懂了。fork()系统调用会返回两次:一次回到父进程,一次回到子进程。

新的进程是为了立即执行新的不同的程序,而接着调用exec*()这族函数就可以创建新的地址空间,并把新的程序载入。(fork()实际上是由clone()系统调用实现的。)

最终,程序会通过exit()系统调用退出执行。这个函数会终结进程并将其占用的资源释放。父进程会通过wait4()系统调用来查询子进程是否终结,这就使得进程拥有了等待特定进程执行的能力。进程退出后被设置为僵死状态,直到父进程调用wait()或waitpid()为止。

知道了进程不仅仅是由一段执行代码组成的,咱们就说说linux下的进程的大概过程。其实一个进程就相当于一个软件的动态执行(严格的说是某个软件子系统的动态执行,当然我们可以把该子系统想象成一个子软件,这样会便于理解)。Linux中创建一个进程要用到fork()系统调用,一个子进程的生成是通过拷贝父进程来实现的。fork以后,会返回两次:一次回到父进程,一次回到子进程。为何要返回两次,两次又是如何区别的呢??刚开始我也在像这个问题,因为子进程拷贝了父进程的代码,返回时处于fork()返回点的上下文是一样的,但是返回的值不一样,借此来区分是父进程还是子进程……

这不,新的子进程创建好了,然后干什么?肯定是做不是当前进程的工作,要不创建他干什么?所以,这时候就接着调用exec*()这一族函数,该族函数可以创建新的地址空间,并加载到当前进程执行。

最后,程序通过exit() syscall(系统调用,以后都用这个代指了) 退出执行。这个函数会终结进程并将其占用的资源释放掉。父进程通过wait4() syscall来查询子进程是否终结,这使得进程拥有了等待特定进程执行完的能力(这不就是传说中的同步么?有木有?有木有?哈哈)。进程退出后被设置为僵死状态,知道父进程调用wait()或waitpid()为止(其实他们貌似都是基于wait4()实现的)。

上面就是进程创建到回收的简单过程。子进程由父进程创建,父进程回收,有点恢复现场的感觉,不过在比较安全的系统里面,哪里都可以看的“恢复现场”等类似概念的身影,就像借钱一样,“好借好还再借不难”,做程序也是这个道理,哈哈,慢慢体会,编程里面蕴含很多的哲学道理的。

1、进程描述符及任务结构

在软件设计中,第一就是抽象名词,一切名词都会在计算机中找到它的数据抽象,就是伟大的数据结构童鞋。他可能被抽象成一个变量,一个数组,一个struct,一个对象……可能是任何一种类型,只要满足你的需求,他就是最perfect的抽象。

进程在kernel中是被放在任务队列(task list)中的,task list 是个双向循环链表。链表中的每一项都是task_struct类型,即进程描述符。定义在中,包含着一个具体进程的所有信息

1.1 分配进程描述符

进程有的表达了,但是不能胡乱表达啊,就像追女朋友一样,不能见人就表白,那不成耍流氓了,名额有限,见好就收啊。OS能多道并跑的进程也就那几个,若肆意创建进程,不跑瘫了机子,那就变成病毒程序了,狂吃cpu。Linux使用slab分配器分配task_struct 结构。由slab动态生成task_struct,只需在栈底创建一个新的thread_info ,再用这个结构的数据可以容易的计算出偏移量。

其中包含了task_struct 的指针和进程的相关信息。

1.2 进程描述符的存放

Kernel通过PID唯一标识一个进程,PID是pid_t类型,其实也是int型的,pid最大值是32768 (short int 的Max 值)。可以改其值,在/proc/sys/kernel/pid_max 中,因为大公司的web服务器集群工作时32768个进程多开貌似不够啊。

内核在处理进程时一般是直接通过task_struct进程的,都是通过current宏直接找到或计算当前task_struct的。有的平台寄存器丰富,不用专门计算其值,一直把当前运行进程的值保存在专用的寄存器中就OK。如powerPC用r2寄存器,而x86寄存器少要专门计算。

1.3 进程状态

进程一直处于下面五种状态之一:

TASK_RUNNING//运行状态

TASK_INTERRUPTIBLE//可中断状态

TASK_UNINTRRUPTIBLE//不可中断状态

TASK_ZOMBIE//僵死

TASK_STOPPED//停止

下图是大概的转换过程。不很详细,大家可以search一下……

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

    关注

    68

    文章

    10428

    浏览量

    206517
  • Linux
    +关注

    关注

    87

    文章

    10986

    浏览量

    206712
  • 进程
    +关注

    关注

    0

    文章

    193

    浏览量

    13875
  • Kernel
    +关注

    关注

    0

    文章

    48

    浏览量

    11033

原文标题:揭开OS的面纱,一位嵌入式er 初探Linux kernel之重点Linux的进程管理

文章出处:【微信号:gh_c472c2199c88,微信公众号:嵌入式微处理器】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Linux开发_Linux进程编程

    介绍Linux进程概念、进程信号捕获、进程管理相关的命令的使用等知识点。
    的头像 发表于 09-17 15:38 1097次阅读
    <b class='flag-5'>Linux</b>开发_<b class='flag-5'>Linux</b>下<b class='flag-5'>进程</b>编程

    Linux进程是如何创建出来的?

    Linux 中,进程是我们非常熟悉的东东了,哪怕是只写过一天代码的人也都用过它。但是你确定它不是你最熟悉的陌生人?我们今天通过深度剖析进程的创建过程,帮助你提高对
    发表于 11-15 09:27 438次阅读

    Linux使用Systemd管理进程服务

    今天浩道跟大家分享linux运维中大家很少用到的一个硬核干货,使用 Systemd 管理进程服务。让你体验一下该技巧带来的便捷性!
    发表于 12-12 09:02 335次阅读

    Linux进程管理

    Linux进程管理
    发表于 05-20 10:53

    LINUX下的进程管理问题如何解决

    基于LINUX下的进程管理问题
    发表于 05-20 07:58

    linux系统进程存在状态及管理

    linux系统进程存在状态及管理详解
    发表于 05-21 06:28

    Linux进程管理工具之Supervisor

    Linux进程管理工具Supervisor
    发表于 06-12 10:58

    Linux进程管理

    Linux进程管理 本章主要介绍进程的概念、状态、构成以及Linux进程的相关知识。 掌握
    发表于 04-28 14:57 0次下载

    Linux 2.6进程调度

    分析了与Linux 2.6 进程调度密切相关的一些重要数据结构,详细描述了进程调度的时机、调度的策略和调度器的工作流程,并从算法分析和HackBench 测试两个方面对
    发表于 06-13 10:13 11次下载

    Linux进程管理:什么是进程进程的生命周期

    所有运行在Linux操作系统中的进程都被task_struct结构管理,该结构同时被叫作进程描述。一个进程描述包含一个运行
    的头像 发表于 02-15 14:29 7431次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>进程</b><b class='flag-5'>管理</b>:什么是<b class='flag-5'>进程</b>?<b class='flag-5'>进程</b>的生命周期

    学会Linux进程管理的方法

    Linux 是一种动态系统,能够适应不断变化的计算需求。Linux 计算需求的表现是以进程 的通用抽象为中心的。进程可以是短期的(从命令行执行的一个命令),也可以是长期的(一种网络服务
    发表于 05-16 17:19 667次阅读
    学会<b class='flag-5'>Linux</b><b class='flag-5'>进程</b><b class='flag-5'>管理</b>的方法

    简要剖析Linux系统的进程管理机制_LINUX_操作系统_脚本之家

    ,更详细的说,linux采用了分时管理的方法,所有的任务都放在一个队列中,操作系统根据每个任务的优先级为每个任务分配合适的时间片,每个时间片很短,用户根本感觉不到是多个任务在运行,从而使所有的任务共同
    发表于 04-02 14:46 443次阅读

    Linux进程间通信方法之管道

    上文中我们介绍了进程间通信的方法之一:信号,本文将继续介绍另一种进程间通信的方法,即管道。管道是Linux中使用shell经常用到的一个技术,本文将深入剖析管道的实现和运行逻辑。
    的头像 发表于 05-14 15:47 1583次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>进程</b>间通信方法之管道

    深度剖析Linux进程控制(上)

    Linux中,fork函数是非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程
    的头像 发表于 05-12 10:49 324次阅读
    深度<b class='flag-5'>剖析</b><b class='flag-5'>Linux</b>中<b class='flag-5'>进程</b>控制(上)

    深度剖析Linux进程控制(下)

    Linux中,fork函数是非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程
    的头像 发表于 05-12 10:49 320次阅读
    深度<b class='flag-5'>剖析</b><b class='flag-5'>Linux</b>中<b class='flag-5'>进程</b>控制(下)