进程管理

进程管理
一个进程就是处于可执行期的程序,但不仅仅限于此。它还包括其他的系统资源。打开的文件,挂起的信号,内核的内部数据,处理器状态,进程地址空间等。
进程也是内核进行调度的基本单元。进程描述符(struct task_struct数据结构)包含一个进程的所有信息。内核把进程存放在一个任务队列的双向链表中。
linux内核采用一种特殊的实现方式。内核需要创建一个进程时,通过fork()和exec()族函数实现。
linux的fork()使用写时拷贝页来实现。不需要复制整个进程地址空间,而是让父进程和子进程共享同一个拷贝。只有在需要写时,数据才被复制。从而进程拥有各自的拷贝。fork()实际开销就是复制副进程的页表以及给子进程创建唯一的进程描述符。
fork()一般都是通过clone()来实现。通过参数指明父子进程所要共享的资源。clone()会调用do_fork()来完成创建。
然而do_fork()调用copy_process()实现完成创建的大部分工作。
do_fork()

  • 首先会调用dup_task_struct()为新进程创建一个内核栈,thread_info和task_struct。此时子进程和父进程的描述符完全相同。
  • 检查进程数目是否超过资源的限制。
  • 子进程描述符中许多成员会被初始化或者设置为0。
  • 更新task_struct 的flags成员
  • 新进程分配一个有效的PID
  • 根据传递的参数拷贝或者打开共享的文件,文件系统信息,信号处理函数,进程地址空间等。
  • 为子进程分配时间片,返回子进程的描述符的指针。

回到do_fork()函数。新建的子进程被唤醒并让其运行,也就是子进程先于父进程运行。为了避免写时拷贝:假如父进程继续运行,父进程可能写地址空间内容。则会使子进程进行写时复制整个地址空间。但是一般情况都会在执行fork()之后,使子进程执行另一个新的镜像,这会是所有的数据拷贝失效。影响效率。
进程调度
对于每个处理器,内核都会维护一个可运行队列(runqueue),进行进程调度。linux进程调度基于优先级的调度,为了解决调度函数循环搜索可运行队列所带来的资源开销。linux中每个可运行队列都有两个优先级数组,一个活跃的和一个过期的。优先级数组是一个能够提供O(1)级算法复杂度的数据结构。优先级数组使可运行的处理器的每一种优先级都包含一个相应的队列,这些队列包含相应优先级的可执行进程。
因为每个优先级数组中都会维护一个优先级位图。
优先级数组数据结构

 struct prio_array{
     int nr_active; //任务数目
     unsigned long bitmap[BITMAP_SIZE]; //优先级位图
     struct list_head queue[MAX_PRIO];  //优先级队列
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值