操作系统--进程
2022/2/7 7:14:02
本文主要是介绍操作系统--进程,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
线程和进程
1. 进程
1.1 什么是进程
- 运行中的程序
1.2为什么要有进程呢?
-
为了任务能够交替执行。所以才有了进程的概念。
-
进程是怎样让任务交替执行的?
- 一个程序的用完一个时间片 进程会把程序的执行现场环境(各个cpu寄存器的值 以及PC)保存在进程的PCB中 。下次就可以接着上次的地方继续执行 所以任务就可以交替执行。
-
进程是什么 执行序列和资源+现场环境
1.3 进程是怎样被交替执行
1.4 进程的构成
1.5 进程之间之怎样被切换的
启动磁盘读写 // 设置当前进程状态为阻塞态 pCur.state='W' 将pCur放到DiskWaitQueue schedule() // 一 :schedule 函数 schedule(){ // 从就绪队列中选出下一个准备运行的进程 pNew=getNext(ReadyQueud); // 切换到下一个进程 switch_to(pCur,pNew) } // 二:switch_to函数 switch_to(pCur,pNew){ // 保存上一个进程的执行进度 pCur.ax = CPU.ax; pCur.bx = CPU.bx; ... // 代码段基地址 pCur.cs = CPU.cs; // pc: 指向下一条待执行的指令 pCur.retpc = CPU.pc; // 恢复待执行进程的执行进度 CPU.ax = pNew.ax; CPU.bx = pNew.bx; ... CPU.cs = pNew.cs; CPU.retpc = pNew.pc; }
2. 线程
2.1 为什么要有线程呢?
- 进程切换效率低。怎么保证并发的优势 又能高效的切换 所以有了线程。
- 现场不切换资源(内存) 只切换指令序列
2.2 用户线程是怎么切换的呢?
- 核心是栈的切换
void Yield(){ TCB1.esp=esp; esp=TCB2.esp; }
2.3 用户线程的优缺点?
- 处理器竞争:单纯的用户线程是建立在用户空间,其对内核是透明的,因此其所属进程单独参与处理器的竞争,而进程的所有线程参与竞争该进程的资源。所以还无法利用对核的优势 并且只要有一个线程堵塞 OS会认为整个进程都会被堵塞。
- 使用资源:与所属进程共享进程地址空间和系统资源。
- 调度:由在用户空间实现的线程库,在所属进程内进行调度
2.4 内核线程
2.4.1 为什么要有内核线程
- 为了能够利用多核优势,所以才有了内核线程
2.4.2 用户线程和核心线程是什么关系呢?常用的是一对一
- 用户线程和进程的关系
2.4.3 内核线程的特点
-
内核线程创建和撤销都是操作系统干的事 所以操作系统可感知到线程的存在 ,可以利用多核的优势
-
内核态线程,创建成本高 通常我们会在内核中预先创建一些线程,并反复利用这些线程
2.5 内核线程是怎么实现的呢?(后续待完善)
- 程序
main() { A(); B(); } A(); { //fork是系统调用,引会引起中断 // fork 不仅可以引起切换 也可以引起切换 fork(); }
- _system_call : 初始化时将各种中断处理设置好
_system_call: // 各种压栈 注意是压的是用户寄存器的值 push %ds..%fs pushl %edx... call sys_fork pushl %eax movl _current,%eax // 判断当前线程是否阻塞 cmpl $0,state(%eax) // 切换 jne reschedule // 判断当前线程是否时间片用完 cmpl $0,counter(%eax) // 切换 je reschedule ret_from_sys_call:
// 进程切换函数 void schedule(void){ // 根据调度算法选择一个合适的线程 next=i; // 切换到下个进程 switch_to(next); }
// 系统调用返回 ret_from_sys_call: popl %eax // 回值popl %ebx ... pop %fs ... iret// 返回到int 0x80后面执行 mov res,%eax res=?
int copy_process(int nr,long ebp,long edi,long esi,long gs,long none,long ebx,long ecx,long edx, long fs,long es,long ds,long eip,long cs,long eflags,long esp,long ss) copy_process: // 申请TCB p=(struct task_struct *)get_free_page(); //创建内核栈 p->tss.esp0 = PAGE_SIZE + (long) p; p->tss.ss0 = 0x10; // 创建用户栈(和父进程共用的用户栈) p->tss.ss = ss & 0xffff; p->tss.esp = esp;
3. 进程调度(CPU调度算法)
3.1 什么是cpu调度算法
- 在就绪队列中选择哪个线程执行
3.2 一款很合理的调度算法 应该考虑什么?
- 短时间内让cpu执行更多的任务
3.3 基本的调度算法
- 先来先服务
- 特点:这似乎很公平 但是当一个长作业先运行了 ,那么后面的短作业等待的时间就会很长 不利短作业
- 短作业优先
- 特点:会有优先选择运行时间最短的进程来运行 这有助提高系统吞吐量 但是对长作业不利 很容易造成一种极端的现象 比如一个长作业在就绪队列等待运行 假如这个就绪队列有很多短作业 导致长作业不短往后排 导致长作业一直不会被运行
- 时间片轮转
- 特点 每个进程分配一个时间片 轮流执行 如果进程在时间片结束前提前结束活着阻塞 ,切换到其他进程上。但是用户更希望调度有优先级 每次调度优先级高的
- 高优先级优先
- 特点:每次选择优先级高的运行 如果优先级不能动态调整 那么将导致优先级低的一直被推后
3.4 Linux 0.11 的调度算法
-
时间片+动态调整优先级算法
-
作用counter:优先级 和 时间片
void Schedule(void) //在kernel/sched.c中 { while(1) { c=-1; next=0; i=NR_TASKS; // NR_TASKS 队列的length p=&task[NR_TASKS]; while(--i){ // 1.从就绪队列中找出最大的counter运行 if((*p->state == TASK_RUNNING && (*p)->counter>c) c=(*p)->counter, next=i; } if(c) break; //找到了最大的counter // 动态调整优先级所有任务的的优先级 优先级=1/2*counter + priority(时间片) // 如果任务被调度过那么 counter=0 即 优先级=1/2*0 + priority(时间片) 所有动态调整后 没运行的优先级会被调高 for(p=&LAST_TASK;p>&FIRST_TASK;--p) (*p)->counter=((*p)->counter>>1) +(*p)->priority; } // 切换到下一个进程运行 switch_to(next);}
4. 进程的同步
4.1 什么是进程的同步
- 多个进程间走走停停 按照一定的顺序向前推进
4.2 怎么保证进程间走走停停—信号量
- 信号量:记录一些信息的量 并根据这信息来决定这个进程是唤醒还是睡眠
4.3 信号量的实现
-
struct semaphore { int value;// 记录资源的个数 PCB *queue; //记录等待在该信号量上的进程 } p(semaphore s) // 消费资源 v(semaphore s) // 生产资源 P(semaphore s){ s.value--; if(s.value<0){ sleep(s.quenue); } } V(semaphore s){ s.value++; if(s.value<=0){ wakeup(s.quenue); } }
4.4 信号量的解决生产者和消费者的问题
5. 信号量临界区保护
5.1 为什么要保护信号量
- 假如多个生产着 ,对信号量i进行修改 如果不保护可能导致最终信号量的值是错误的,所以就要互斥进入,如果一个进程在临界区中执行 则其他进程不允许进入
5.2 好的临界区保护原则
-
互斥进入
-
有空让进
-
有限等待
5.3 两个进程怎么利用代码实现临界资源的保护
5.4 多个进程怎么利用代码实现
- 面包店算法
5.5 硬件实现
这篇关于操作系统--进程的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-12如何创建可引导的 ESXi USB 安装介质 (macOS, Linux, Windows)
- 2024-11-08linux的 vi编辑器中搜索关键字有哪些常用的命令和技巧?-icode9专业技术文章分享
- 2024-11-08在 Linux 的 vi 或 vim 编辑器中什么命令可以直接跳到文件的结尾?-icode9专业技术文章分享
- 2024-10-22原生鸿蒙操作系统HarmonyOS NEXT(HarmonyOS 5)正式发布
- 2024-10-18操作系统入门教程:新手必看的基本操作指南
- 2024-10-18初学者必看:操作系统入门全攻略
- 2024-10-17操作系统入门教程:轻松掌握操作系统基础知识
- 2024-09-11Linux部署Scrapy学习:入门级指南
- 2024-09-11Linux部署Scrapy:入门级指南
- 2024-08-21【Linux】分区向左扩容的方法