linux读书笔记(3章)

标签(空格分隔): 20135328陈都

第三章 进程管理

3.1 进程

  • 进程就是处于执行期的程序(目标码存放在某种存储介质上)。但进程并不仅仅局限于一段可执行程序代码( Unix称其为代码段,text section)。通常进程还要包含其他资源,像打开的文件,挂起的信号,内核内部数据,处理器状态,一个或多个具有内存映射的内存地址空间及一个或多个执行线程(threa do fexecution),当然还包括用来存放全局变量的数据段等。

  • 程序本身并不是进程,进程是处于执行期的程序以及相关的资源的总称。实际上,完全可能存在两个或多个不同的进程执行的是同一个程序。并且两个或两个以上并存的进程还可以共享许多诸如打开的文件、地址空间之类的资源。

  • 通常,创建新的进程都是为了立即执行新的、不同的程序,而接着调用exec。这组函数就可以创建新的地址空间,并把新的程序载入其中。

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

3.2进程描述符及任务结构

进程描述符中包含的数据能完整地描述一个正在执行的程序:它打开的文件,进程的地址空间,挂起的信号,进程的状态,还有其他更多信息(见下图)

3.2.1 分配避程描述符

  • 在x86 上, structtbre叫~info在文件<asm/也read_info.h>中定义如下:

每个任务的thread_info 结构在色的内核栓的尾端分配。结构中task 域中存放的是指向该任务实际task_struct 的指针。

3.3进程创建

Unix 的进程创建很特别。许多其他的操作系统都提供了产生(spawn)进程的机制,首先在新的地址空间里创建进程,读入可执行文件,最后开始执行。Unix 采用了与众不同的实现方式,它把上述步骤分解到两个单独的函数中去执行: forkO 和exec()首先,fork()通过拷贝当前进程创建一个子进程。子进程与父进程的区别仅仅在于PID(每个进程唯一)、PPID(父进程的进程号,子进程将其设置为被拷贝进程的PID)和某些资源和统计量(例如,挂起的信号,它没有必要被继承〉。exec()函数负责读取可执行文件并将其载入地址空间开始运行。把这两个函数组合起来使用的效果跟其他系统使用的单一函数的效果相似。

3.3.1 写时拷贝

Linux 的fork()使用写时拷贝(copy-on-write)页实现。写时拷贝是一种可以推迟甚至免除拷贝数据的技术。内核此时并不复制整个进程地址空间, 而是让父进程和子进程共享同-个拷贝.只有在需要写入的时候,数据才会被复制,从而使各个进程拥有各自的拷贝。也就是说,资源的复制只有在需要写入的时候才进行,在此之前,只是以只读方式共享。

3.3.2 fork()

Linux 通过clone()系统调用实现fork()。这个调用通过一系列的参数标志来指明父、子进程需要共享的资源。
do_fork 完成了创建中的大部分工作,它的定义在kemeVfork.c 文件中。该函数调用copy_
process()函数,然后让进程开始运行。copy_process()函数完成的工作很有意思:

  1. 调用dup_task_ struct()为新进程创建一个内核枝、也read_info结构和task_struct,这些值与当前进程的值相同。此时,子进程和父进程的描述符是完全相同的。
  2. 检查并确保新创建这个子进程后,当前用户所拥有的进程数目没有超出绘色分配的资源的限制。
  3. 子进程着手使自己与父进程区别开来。进程描述符内的许多成员都要被清0 或设为初始值.那些不是继承而来的进程描述符成员,主要是统计信息。task_struct 中的大多数数据都依然未被修改。
  4. 子进程的状态被设置为TASK_UNJNTERRUPTIBLE,以保证它不会投入运行。
  5. copy _process()调用copy_flags()以更新task_struct 的组ags 成员.表明进程是否拥有超级用户权限的PF_SUPE盯RIV标志被清0。表明进程还没有调用exec()函数的PF_FOR.KNOEXEC标志被设置。
  6. 调用alloc _pid()为新进程分配一个有效的PID。
  7. 根据传递给clone()的参数标志,copy_process()拷贝或共享打开的文件、文件系统信息、信号处理函数、进程地址空间和命名空间等。在一般情况下,这些资源会被给定进程的所有线程共享:否则,这些资源对每个进程是不同的,因此被拷贝到这里。
  8. 最后, copy_process()傲扫尾工作并返回一个指向子进程的指针。
    再回到do_fork()函数,如果copy_process()函数成功返回,新创建的子进程被唤醒并让其投入运行。内核有意选择子进程首先执行。.因为一般子进程都会马上调用exec()函数,这样可以避免写时拷贝的额外开销,如果父进程首先执行的话,有可能会开始向地址空间写入。

3.3.3 vfork()

除了不拷贝父进程的页表项外,vfork()系统调用和fork()的功能相同。

3.4 线程在linux中的实现

钱程机制是现代编程技术中常用的一种抽象概念. 该机制提供了在同一程序内共享内存地址
空间运行的一组线程。这些线程还可以共享打开的文件和其他资源.线程机制支持并发程序设计技术(concurrentprogramming),在多处理器系统上,它也能保证真正的井行处理( parallelism )。Linux实现线程的机制非常独特。从内核的角度来说,它并没有线程这个概念。Linux 把所
有的钱程都当做进程来实现。

  • 传递给clone()的参数标志决定了新创建进程的行为方式和父子进程之间共辜的资源种类。下表列举了这些clone()周到的参数标志以及它们的作用,这些是在<linux/scbed.h>中定义的。
    -

3.4.2 内核编程

内核经常需要在后台执行一些操作。这种任务可以通过内核线程( kernel thread)完成————独立运行在内核空间的标准进程。内核线程和普通的进程阔的区别在于内核线程没有独立的地址空间(实际上指向地址空间的mm指针被设置为NULL ).它们只在内核空间运行,从来不切换到用户空间去.内核进程和普通进程一样,可以被调度,也可以被抢占.

3.5 进程终结

虽然让人伤感,但进程终归是要终结的(说得好像真的很伤感一样)。当一个进程终结时,内核必须释放它所占有的资掠并把这一不幸告知其父进程。

3.5.2 孤儿进程造成的进退维谷

如果父进程在子进程之前退出,必须有机制来保证子进程能找到一个新的父亲,否则这些成为孤儿的进程就会在退出时永远处于僵死状态,白白地艳费内存。

3.6 小结

  • 在本章中,我们考察了操作系统中的核心概念一一进程。
  • 进程是一个非常基础、非常关键的抽象概念,位于每一种现代操作系统核心位置,也是我们拥有操作系统的最终原因。

# linux读书笔记(3章)的更多相关文章

  1. linux读书笔记(5章)

    linux读书笔记(5章) 标签(空格分隔): 20135328陈都 第五章 系统调用 5.1 与内核通信 系统调用 让应用程序受限的访问硬件设备 提供创建新进程并与已有进程通信的机制 提供申请操作系 ...

  2. 跟着鸟哥学Linux系列笔记3-第11章BASH学习

    跟着鸟哥学Linux系列笔记0-扫盲之概念 跟着鸟哥学Linux系列笔记0-如何解决问题 跟着鸟哥学Linux系列笔记1 跟着鸟哥学Linux系列笔记2-第10章VIM学习 认识与学习bash 1. ...

  3. STL源码分析读书笔记--第二章--空间配置器(allocator)

    声明:侯捷先生的STL源码剖析第二章个人感觉讲得蛮乱的,而且跟第三章有关,建议看完第三章再看第二章,网上有人上传了一篇读书笔记,觉得这个读书笔记的内容和编排还不错,我的这篇总结基本就延续了该读书笔记的 ...

  4. 《C++ Primer》读书笔记 第一章

    读<C++ Primer>才知道,自己对C++知之甚少... 写个博客记录下自己C++的成长,只是读书笔记,不是对<C++ Primer>知识点的总结,而是对自己在书上看到的以 ...

  5. 跟着鸟哥学Linux系列笔记2-第10章VIM学习

    跟着鸟哥学Linux系列笔记0-扫盲之概念 跟着鸟哥学Linux系列笔记0-如何解决问题 跟着鸟哥学Linux系列笔记1 常用的文本编辑器:Emacs, pico, nano, joe, vim VI ...

  6. 《疯狂Java:突破程序员基本功的16课》读书笔记-第一章 数组与内存控制

    很早以前就听过李刚老师的疯狂java系列很不错,所以最近找一本拿来拜读,再此做下读书笔记,促进更好的消化. 使用Java数组之前必须先对数组对象进行初始化.当数组的所有元素都被分配了合适的内存空间,并 ...

  7. 《Linux内核设计与实现》读书笔记 第二章 从内核出发

    一.获取内核源码 1. Git git实际上是一种开源的分布式版本控制工具. Linux作为一个开源的内核,其源代码也可以用git下载和管理 - 获取最新提交到版本树的一个副本 - $ git clo ...

  8. Linux读书笔记第三、四章

    第三章 主要内容: 进程和线程 进程的生命周期 进程的创建 进程的终止 1. 进程和线程 进程和线程是程序运行时状态,是动态变化的,进程和线程的管理操作(比如,创建,销毁等)都是有内核来实现的. Li ...

  9. Linux读书笔记第一、二章

    第一章    Linux内核简介 1.1Unix历史 Unix特点:1.很简洁 2.所有东西都被当成文件对待 3.Unix内核和相关的系统工具软件都是用C语言编写而成 4.进程创建非常迅速 1.2追寻 ...

随机推荐

  1. 阿里八八Alpha阶段Scrum(12/12)

    今日进度 俞鋆: 和前端对接,完成了注册接口的对接写了一部分数据同步接口. 李嘉群: 完成了注册界面与服务器的对接 黄梅玲: json数据解析并在listview中显示(还未完成) 王国超: 今天开始 ...

  2. 【Alpha 冲刺】 7/12

    今日任务总结 人员 今日原定任务 完成情况 遇到问题 贡献值 胡武成 建立数据库 已完成 孙浩楷 完成作业列表界面 已完成 胡冰 完成作业展示页面 已完成 练斐弘 完成课件列表页面 未完成 时间不够 ...

  3. web.py利用模板的详细步骤

    <python网络编程学习笔记(10):webpy框架>(http://www.cnblogs.com/xiaowuyi/archive/2012/11/15/2771099.html#3 ...

  4. 一个将lambda字符串转化为lambda表达式的公共类

    一个将lambda字符串转化为lambda表达式的公共类.StringToLambda 使用方式如下: var module = new Module(); url = url.ToLower();/ ...

  5. 二分法php

    二分法.分别使用while循环的方法和递归调用的方法. <?php // 二分法的使用数组必须是有序的,或升序,或降序 $arr = array( 1, 3, 5, 7, 9, 13 ); // ...

  6. Docker一键部署Hadoop心得(一)

    最近一直在折腾使用docker一键部署全分布式hadoop集群,虽然一键部署的脚本写好了并且可以成功运行出各个节点,但在运行一个wordcount实例时出现了错误,错误如下: java.io.IOEx ...

  7. Linux服务-openssh

    目录 1. 使用 SSH 访问远程命令行 1.1 OpenSSH 简介 1.2 SSH 版本 1.3 SSH 认证方式 1.4 openSSH 的工作模式 1.5 Secure Shell 示例 1. ...

  8. 大数据入门第二十三天——SparkSQL(二)结合hive

    一.SparkSQL结合hive 1.首先通过官网查看与hive匹配的版本 这里可以看到是1.2.1 2.与hive结合 spark可以通过读取hive的元数据来兼容hive,读取hive的表数据,然 ...

  9. 20155204《网络对抗》Exp 6 信息搜集与漏洞扫描

    20155204<网络对抗>Exp 6 信息搜集与漏洞扫描 一.实验后回答问题 1.哪些组织负责DNS,IP的管理. 互联网名称与数字地址分配机构,简称ICANN机构,决定了域名和IP地址 ...

  10. CDH上Cloudera Management Service 各个角色迁移至其他节点

    1.首先查看Cloudera Management Service下有哪些服务,cdh版本为5.9.2: 可以看到基本上有以上6个角色: 2.停止所有角色,并执行删除: 3.找到集群中另外一个节点,添 ...