Chinaunix首页 | 论坛 | 博客
  • 博客访问: 106557
  • 博文数量: 48
  • 博客积分: 12
  • 博客等级: 民兵
  • 技术积分: 276
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-21 21:44
文章分类
文章存档

2013年(6)

2012年(42)

我的朋友

分类:

2013-01-07 16:12:14

原文地址:进程管理的读书笔记 作者:hyouyan

   一个进程就是处于执行期的程序,但进程并不局限于一段可执行程序代码。通常进程还要包含像存放全局变量的数据段,打开的文件,挂起的信号等,当然还包含地址空间及一个或几个执行线程(又称线程)。
 
   线程是在进程中活动的对象。每个线程都拥有一个独立的程序计数器,进程栈和一组进程寄存器。内核调度的对象是进程,而不是进程。
 
   进程提供两种虚拟机制:虚拟处理器和虚拟内存。
 
   通常创建新的进程都是为了执行新的,不同的程序,而接着调用exec()这族函数就可以创建新的地址空间,并把新的程序载入。
  
   最终,程序通过exit()系统调用退出执行。这个函数会终结进出进程并将其占用的资源释放掉。
 
2.1 进程描述符及任务队列
 
   内核把进程存放在叫做任务队列(task list)的双向循环链表中。链表的每一项都是类型为task_struct、称为进程描述符(process descriptor)的结构,该结构内包含了内核管理一个进程所需的所有信息。
   
   linux通过slab分配器分配task_struct结构,这样能达到对象复用和缓存着色的目的
 
   内核通过一个唯一的进程标示值或PID来标示每个进程
  
   进程的状态:
    (1)TASKK-RUNNING(运行)进程可执行,它或者正在执行,或在运行队列中等待执行。
    (2)TASK_INTERRUPTIBLE(可中断)进程正在睡眠(也就是说它被阻塞),等待某些条件的的达成。
    (3)TASK_UNINTERRUPTIBLE(不可中断)除了不会因为接受到信号而被唤醒从而投入运行,这个状态与可打断状态相同。
    (4)TASK_ZOMBIE(僵死)该进程已经结束了,但是其父进程还没有调用wait4()系统调用
    (5)TASK_STOP PED(停止)进程停止执行;进程没有投入运行也不能投入运行。
   
    内核最后使用set_task_state(task,state)函数将指定的进程设置为指定的状态。
 
    linux进程之间存在一个明显的继承关系。所有的进程都是PID为1的init进程的后代。内核在系统启动的最后阶段启动init进程。该进程读取系统的初始化脚本(initscripts)并执行其他的相关程序,最终完成系统启动的整个过程。
 
    进程间的关系存放在进程描述符中。每个task_struct都包含一个指向其父进程task_struct,叫做parent的指针,还包含一个称为children的子进程链表。所以对于当前进程可以通过下面的代码获得其父进程的进程描述符
    struct task_struct *task=current->parent;
 
2.2 进程创建
   一:fork()通过拷贝当前进程创建一个子进程。子进程与父进程的区别仅仅在于PID,PPID和某些资源和统计量。二:exec()函数负责读取可执行文件并将其载入地址空间开始运行。
   linux通过clone()系统调用实现fork()。fork,vfork()和_clone()库函数都根据各自需要的参数标志区调用clone()。然后由clone()去调用do_fork()。
 
2.3 线程在linux中的实现
  
   该机制提供了在同一程序内共享内存地址空间运行的一组线程。这些线程还可以共享打开的文件和其他资源。线程机制支持并发程序设计技术。
   内核线程:
  
    内核经常需要在后台执行一些操作。这种任务可以通过内核线程(kernel thread)完成---独立运行在内核空间的标准进程。内核线程和普通的进程间的区别在于内核线程没有独立的地址空间(实际上它的mm指针被设置为NULL)。它们只在内核空间运行,从来不切换到用户空间去。内核进程和普通进程一样,可以被调度,也可以被抢占。
  
   内核线程只能由其他内核线程创建。新的任务也是通过向普通的clone()系统调用传递特定的flags参数而创建的,内核线程会将它在创建时得到的函数永远执行下去。该函数通常由一个循环构成,在需要的时候,这个内核线程就会被唤醒和执行,完成了当前任务,它会自行休眠。
 
 
阅读(293) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~