操作系统相关面试题

 

 

互斥锁 自旋锁

互斥锁:线程会从阻塞 ->运行,过程中有上下文的切换,cpu的抢占,信号的发送等开销。

自旋锁:线程一直是死循环检测锁的标志位

机制不复杂,锁被持有的时间短,不希望在调度上花费太多的成本

自旋锁通常作为底层原语用于实现其他类型的锁

如何避免死锁

银行家算法:系统对进程发出的每一个资源申请进行检查

系统调用?

API与系统调用的区别:

一个系统调用对应一个API,但一个API里面封装多个系统调用

执行流程

在内核栈保存寄存器

调用系统调用服务例程

退出系统调用处理程序

fork做了什么?

fork源码解析

do_fork()

查找pidmap_array()位图,为子进程分配新的PID

调用copy_process,将pid传入,返回新的task_struct地址

copy_process()

创建task_struct结构体指针,检查参数,

调用dup_task_struct(),将父进程的task_struct传入参数,为子进程获取进程描述符

dup_task_struct()

创建task_struct,thread_info结构体指针

alloc_task_struct为新进程获取进程描述符,保存至tsk中

alloc_thread_info()获取一块空闲内存区,保存在ti中

atomic_inc(p->user->process)检查进程数

拷贝所有的进程信息

copy all process information

atomic_inc(&oldmm->mm_users);	// 父进程的地址空间引用计数加一
mm = oldmm;			// 将父进程地址空间赋给子进程
  • 否则,就要创建新的地址空间,并从当前进程复制 mm 的内容
mm = allocate_mm();
memcpy(mm, oldmm, sizeof(*mm));

复制父进程的线性区和页表

copy_page_range()

  • 创建新的页表;
  • 复制父进程的页表来初始化子进程的新页表;
    私有/可写的页( VM_SHARED 标志关闭/ VM_MAYWRITE 标志打开)所对应的权限父子进程都设为只读,以便于 Copy-on-write 机制处理

调用 copy_thread() 用父进程的内核栈初始化子进程的内核栈

调用 sched_fork() 完成对新进程调度程序数据结构的初始化,将新进程状态设为 TASK_RUNNING

fork() 和 vfork() 参数是写死的,而 clone() 是可选的,
它可以选择当前创建的进程哪些部分是共享的,哪些部分是独立的;

vfork() 是历史的产物,当调用 fork() 的时候,
需要将父进程的线性区和页表都拷贝一份,而调用 exec() 执行新程序后,
又要把所有页表删除重置新的页表,建立映射关系,效率很低;

所以要有 vfork(),vfork() 的 clone_flags 位置了 CLONE_VM ,
表示共享父进程的地址空间,vfork() 中创建的进程没有分配自己的地址空间,
而是通过一个 mm_struct 指针指向父进程的地址空间,
这个进程是为了在之后调用 exec() 执行新的程序;

而在有了 Copy-on-write 技术后,fork() 出的子进程只创建了自己的地址空间,
然后用父进程的地址空间初始化,每个页表的项置为父进程的页表项,
共享父进程的物理页面,并将所有 私有/可写 页面改为只读;

当我们改变父子进程的数据后,cpu 在运行过程中会发生一个缺页错误,
cpu 转交控制权给操作系统,操作系统查找 VMA 发现该页权限为只读,但所在段又是可写的,
产生一个矛盾,这就是识别 Copy-on-write 的方法,
接着 OS 给子进程分配一个新的物理页,并将页表该页的地址修改成新的物理页地址;

这样 fork() 后再调用 exec() 就不用那么麻烦了,
可以直接将新的物理页与子进程的虚拟空间建立映射

下面是mm_struct和vm_area_struct

struct mm_struct
{
	struct vm_area_struct * mmap; 
    // 指向线性区对象的链表头
	struct rb_root mm_rb;
    // 指向线性区对象的红黑树的根
	pgd_t * pgd; 
    // 指向页全局目录
	atomic_t mm_users; 
    // 次使用计数器,存放共享 mm_struct 数据结构轻量级进程的个数
	atomic_t mm_count;
    // 主使用计数器,每当 mm_count 递减,内核就要检查它是否为0,如果是就要解除这个内存描述符
}

task_struct的结构

进程调度算法中基于优先级的调度

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值