本文转载自;http://blog.chinaunix.net/uid-25014876-id-64866.html

linux设备驱动归纳总结(四):1.进程管理的相关概念

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

接下来的几节我会大概的讲一下内核进程的一些概念,其实应该在学习系统编程时候就应该知道的。。我参照的书籍是《linux内核设计与实现》(第三版)。我会尽可能地跳开内核代码,简述一下原理。

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

一、什么是进程

简单的说,进程就是正在运行的程序,一个程序可以同时有多个进程。学过C语言都知道,程序运行时并不是只有代码,还包含其他的资源,如打开的文件,信号,全局变量等等。我在《操作系统原理》中看过一个很生动很深刻的例子:一个人对照着菜谱做菜。在这例子中,人就是内核,菜谱就是程序,做菜的过程就是进程,而菜、锅就是这个进程的资源。

内核为线程提供了两种技术:虚拟处理器和虚拟内存。这就是说,每个进程都傻乎乎的认为自己独占着CPU和享用这4G的内存,确不知道内核在背后调度进程和给每个进程4G的虚拟地址。

进程由fork创建,通过exit退出。

有人或许会问,那线程是什么?线程就是一种特殊的进程。

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

二、进程是用什么结构体来维护

内核将所有的进程放在叫任务队列(task list)的双向循环链表中,链表中的每个项都是类型为task_struct、称为进程描述符的结构。每个进程描述符包含着一个进程的所有信息,驱动开发中我用得最频繁的有两个成员,pid(进程标识值)和comm(当前进程的所执行的程序文件名称)。

来张形象点的图:

获得当前正在进行的进程进程描述符也很简单,使用全局项current就可以获得。

/*4th_mutex/4th_mutex_1/1st/test.c*/

113 P_DEBUG("[%s]:pid[%d]\n", current->comm, current->pid);

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

三、进程的状态

我只说5种,其中前两种是之前在等待队列的时候介绍过。

1)TASK_RUNNING(运行):该状态出现在进程正在运行,或者已经放在运行队列中等待执行(对应操作系统原理上所说的就绪状态)。这里要注意的是等待执行和休眠是两码事。

2)TASK_INTERRUPTIBLE(可中断休眠):这就是休眠状态中一种,之所以说可中断,就是说除了可以被其他进程从等待队列唤醒以外,还可以接送到信号而唤醒,这是常用的休眠状态。

3)TASK_UNINTERRUPTIBLE(不可中断休眠):这就是休眠状态的另一种,只能从等待队列被唤醒。因为它如此霸道,所以很少有人使用。

4)TASK_ZOMBIE(僵死):这种情况出现在进程结束后,但父进程还有来回收该进程的进程描述符。

5)TASK_STOPPED(停止):一看就知道,进程停止执行。

来个图来对照前四种状态的转换:

由上图可以看到用户空间的进程有fork()系统调用产生,如果运行途中没有任何阻塞,它会在最后调用do_exit将进程的状态转为TASK_ZOMBIE。等待父进程来收尸。接下来就要简单地说一下进程的创建和进程的终结。

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

四、进程的创建

进程的创建一般分两步:

1、调用fork():

在系统编程时,我们一般都是调用fork()来创建新的用户进程。

先说一下传统的forl()的实现,传统的fork()被调用后,内核会拷贝父进程的所有资源给新建的子进程。要知道这是一个多愚蠢的操作,如果新建子进程是打算执行另一个新程序,之前的拷贝过程就白费了。

出于这样的原因,linux的fork()有了写时拷贝(copy-on-write)技术。从字面上就能理解意思,父进程创建子进程后,他给子进程创建一个文件描述符,并且与子进程以只读方式共享原有的资源,只有在子进程或者父进程修改资源时,资源才会被复制。所以说,在不修改资源的情况下,fork()的实际开销就两样:

1)复制父进程的页表给子进程。大家应该都知道,linux内存管理使用的页式管理,只要也就是说,只要把父进程的页表复制给子进程,子进程就能在页表中找到与父进程共享的4G虚拟地址了。

2)为子进程创建唯一的进程描述符。这个就不用解释了,进程与进程描述符是一一对应的。

fork具体调用的什么函数我就不详细说了,不过应该有这样的一个概念:

fork->clone->do_fork()->copy_procrss:

fork()系统调用根据提供的参数调用clone(),然后clone()去调用do_fork(),其中do_fork中完成了创建的大部分操作,里面有一个主要的函数copy_process()。

2、调用exec():

一般的,创建的子进程都不是为了完成父进程中的任务,而是需要执行新的任务。exec()的作用就是读取可执行文件并加载到地址空间开始运行,可以类比成命令”./xxxxx”。如果fork()后子进程调用exec()执行新的代码,就不需要拷贝父进程的资源了。所以,一般fork()之后都是子进程先运行。

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

五、进程的终结:

一般的,进程调用exit()结束进程。相应的,exit()是调用do_exit()进行删除进程的资源和改变进程状态等操作。

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

六、什么是进程上下文:

用户态的应用程序执行系统调用时,它就会陷入内核空间,此时,我们称内核“代表进程执行”并处于进程上下文。简单的说,以我们之前写的驱动举例,当应用成调用open,他就会陷入内核调用驱动函数中的test_open,此时内核就 处于进程上下文了。

值得一提的是,在进程上下文时,current始终有效,它还是指向应用层中的进程,所以在”1st”的例子中,tesp_open打印出来的进程号current->pid与应用层是一样的。

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

七、线程、进程和内核线程程又是怎么样的关系:

线程,它是进程活动中的对象,最通俗的解释,一个进程里面可以有一个或者多个线程,它们共同享用进程的资源。

内核线程,独立运行在内核空间的标准进程,但没有独立的运行空间,只运行在内核空间,但和普通进程一样被调度和抢占。

总的来说,线程(又叫用户线程)和内核线程都是进程的特殊形式,它们的创建同样也是通过调用clone()。它们和进程的最大区别在于它们没有独立的4G虚拟空间。

而线程和内核线程的区别就是:线程存在与用户态,内核线程存在与内核态。

同时需要强调的是,进程是存在于用户态的。

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

八、总结:

今天只是介绍了进程的一些基本的概念,为以后的进程调度、并发、竞态等理论打基础。

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

linux设备驱动归纳总结(四):1.进程管理的相关概念【转】相关推荐

  1. linux 设备驱动总结,linux设备驱动归纳总结.doc

    linux设备驱动归纳总结 linux设备驱动归纳总结 内核:用于管理软硬件资源,并提供运行环境.如分配4G虚拟空间等. linux设备驱动:是连接硬件和内核之间的桥梁. linux系统按个人理解可按 ...

  2. 【Linux开发】linux设备驱动归纳总结(四):5.多处理器下的竞态和并发

    linux设备驱动归纳总结(四):5.多处理器下的竞态和并发 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...

  3. 【Linux开发】linux设备驱动归纳总结(四):2.进程调度的相关概念

    linux设备驱动归纳总结(四):2.进程调度的相关概念 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...

  4. linux设备驱动归纳总结

    前言: (总结已经基本写完,这段时间我会从新排版和修正.错误总会有的,望能指正!) 前段时间学习了嵌入式驱动,趁着没开始找工作,这段时间我会每天抽出时间来复习. 我的总结是根据学习时的笔记(李杨老师授 ...

  5. 【Linux开发】linux设备驱动归纳总结(七):2.内核定时器

    linux设备驱动归纳总结(七):2.内核定时器 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...

  6. 【Linux开发】linux设备驱动归纳总结(一):内核的相关基础概念

    linux设备驱动归纳总结(一):内核的相关基础概念 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...

  7. 【Linux开发】linux设备驱动归纳总结(六):3.中断的上半部和下半部——tasklet...

    linux设备驱动归纳总结(六):3.中断的上半部和下半部--tasklet xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...

  8. linux块设备驱动中断程序,linux设备驱动归纳总结(六):1.中断的实现

    linux设备驱动归纳总结(六):1.中断的实现 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...

  9. linux设备驱动归纳总结--转载小白的博客

    主要是为了自己浏览方便... linux设备驱动归纳总结 linux设备驱动归纳总结(一):内核的相关基础概念 linux设备驱动归纳总结(二):模块的相关基础概念 linux设备驱动归纳总结(三): ...

最新文章

  1. 经典模式流水灯实验的个人总结和思考
  2. C++——C++11中的defalut和delete关键字
  3. Fatal error: Maximum function nesting level of '100' reached, aborting!
  4. ERDAS遥感图像配准、及其它一些基本处理
  5. webdriver高级应用- 操作日期控件
  6. php相差天数,php获取给定日期相差天数
  7. 解决python使用images2gif模块时候报错:Type error Argument 1 must be string or buffer not none
  8. 在任务栏中添加控件 如360小助手、QQ桌面小助手
  9. 有哪些免费的软件资源分享网站,软件资源网站大全导航
  10. 制作游戏3D模型都有哪些步骤流程
  11. Windows 10 下生成 ssh 密钥
  12. 计算机电缆的最小弯曲半径,电缆最小弯曲半径-知道电缆长度直径弯曲半径,怎么计算出电缆盘大小-电工基础 - 电工屋...
  13. 如何从初级程序员顺利晋升到高级程序员?
  14. 浅谈电动汽车V2G系统中的漏电问题
  15. 超低延时监控视频多终端发布解决方案
  16. 多级放大电路的频率响应(上限截止频率FH、下限截止频率FL)
  17. Excel合并单元格如何填充序号
  18. vulnhub靶场——VULNERABLE DOCKER: 1 Easy
  19. ffmpeg对mpeg2-TS解析的最详细分析 ffmpeg
  20. 判断一个数的所有因数的个数是偶数还是奇数

热门文章

  1. 1.4操作系统的变革
  2. 我的日常工具——gdb篇
  3. 如何访问“我的网站”
  4. linux虚拟机网卡启动失败问题处理
  5. mysql slave 能写吗_MySQL主从复制(Master-Slave)与读写分离(MySQL-Proxy)实践
  6. 【数字信号处理】相关函数与线性卷积关系 ( 卷积概念 | 相关函数概念 | 相关函数与线性卷积对比 | x(-m) 共轭 与 y(m) 的卷积就是两个信号 位移 m 的相关函数 )
  7. 【Android 逆向】函数拦截原理 ( 可执行程序基本结构 | GOT 全局偏移表 | 可执行程序函数调用步骤 )
  8. 【开发环境】010 Editor 工具 ( 工具下载 | 二进制文件分析模板模板安装 | 快捷键查看与设置 )
  9. 【MATLAB】变量 ( 特殊变量和常量 | 关键字 | 调用优先级 | 数值显示格式 )
  10. 【C 语言】Windows 下使用 gcc 编译器 ( 常用的编译器 | Qt 中的 gcc 编译器 | 独立安装 MinGW )