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. Sqlserver数据库还原一直显示“正在还原…”解决方法

    --恢复并且回到可访问状态,要执行 RESTORE database 数据库名  with recovery

  2. Invalid action class configuration that references an unknown class named [XX] .

    多次遇到这个错误,难以解决,有时候出现,有时候没有,很神奇,今天发现了一点端倪,虽然说不上找到了所有导致这个bug的原因.至少,也是很主要的一种了. 其实,透过结果,如果debug用心,一行代码一行代 ...

  3. Oracle Database(rdbms) 12.2 安装组件

    1. 工具用法 su - oracle $ $(orabasehome)/perl/bin/perl $ORACLE_HOME/rdbms/admin/catcon.pl Usage: catcon ...

  4. 微信jsapi退款操作

    引自网络“ 前期准备:当然是搞定了微信支付,不然怎么退款,这次还是使用官方的demo.当然网上可能也有很多大神自己重写和封装了demo,或许更加好用简洁,但是我还是不提倡用,原因如下:(1)可能功能不 ...

  5. MyBatis的javaType和ofType的区别

    javaType和ofType都是用来指定对象类型,保证了类型安全.反向用select是必须要用ofType.javaType是指POJO类中的属性类型,比如下面的id,text,url,parent ...

  6. MacOS 快速搭建Odoo开发环境

    转载请注明原文地址:https://www.cnblogs.com/cnodoo/p/9307325.html  一:安装PostgreSQL 下载并安装PostgreSQL数据库:http://do ...

  7. 理解javascript观察者模式(订阅者与发布者)

    什么是观察者模式? 观察者模式又叫做发布订阅模式,它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生改变时就会通知所有观察着对象.它是由两类对象组成,主题和观察者 ...

  8. POJ 3687 Labeling Balls(反向拓扑+贪心思想!!!非常棒的一道题)

    Labeling Balls Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16100   Accepted: 4726 D ...

  9. 串口通信DMA中断

    这是以前学32的时候写的,那时候学了32之后感觉32真是太强大了,比51强的没影.关于dma网上有许多的资料,亲们搜搜,这里只贴代码了,其实我也想详详细细地叙述一番,但是自己本身打字就慢,还有好多事情 ...

  10. Linux线程的信号量同步

    信号量和互斥锁(mutex)的区别:互斥锁只允许一个线程进入临界区,而信号量允许多个线程同时进入临界区. 不多做解释,要使用信号量同步,需要包含头文件semaphore.h. 主要用到的函数: int ...