时间片轮转
就是给每个进程分配一个时间片,一般设置时10ms,这个能保证每个进程不会太饥饿,但是平均周转时间相对较大,并且会有额外的进程切换的开销
多级反馈队列
也就是有很多个就绪队列,然后不同的队列使用的调度算法不一样,使用比较灵活
实时调度
给每个任务定义了一个开始时间,和截止时间,要在这个区间将这个任务完成
分为了硬时限和软时限
硬时限如果不行,错过会导致严重后果,必须在最坏情况都要完成
软事先不能满足的话降低要求,尽量满足要求就行
同步问题:
现实生活中例子:
冰箱买面包
A想吃面包
去冰箱找
发现没有 B想吃面包
去买 去冰箱找
发现没有
去买
这样就买了重复的面包,如果在计算机内,弄出很多重复的事情将不可估量,然后就考虑做法
这里就牵扯到了计算机的同步,把这些操作都定义为原子操作,那么那个地方就是临界区,同时只能有一个人访问
临界区的实现有三种
1,禁用中断 也就是直接用硬件禁用中断掉,那么无法产生进程切换, 从而达到只有一个访问,但是可能导致其他进程进入饥饿,系统也会停止下来
2,软件操作 使用一些共享变量
3,高级抽象 化为原子操作
信号量
代表资源的数量,有两个操作 P,V
P :代表我申请一个资源,资源-1,如果<0,那么处于等待状态
V:代表释放一个资源,资源+1,如果<=0,代表有人申请了但是处于等待状态,那么我就去唤醒它
int num=3; P(){ num--; if(num<0) { add 当前进入等待队列 block 堵塞在这等待有资源 } } V (){ num++; if(num<=0){ remove 从队列中删除 wakeup 唤醒一个线程 } }
经典问题: 生产者-消费者
要求:一个桶子可以装n件物品,生产者不断的在制作东西,消费者不断在拿东西,但是对桶子的操作只能同一时间做一个,如果桶子满了,那么生产者需要等待,如果桶子是空的,那么消费者需要等待
int x=1; //代表互斥信号量,同一时间只能一个人操作桶 int y=0; //代表现在桶里的东西数量 int z=n; // 代表现在桶里剩余空间 product(){ //生产者 P(z); P(x); 制作东西 V(x); V(y); } custmer(){ P(y); P(x) ; 拿东西 V(x); V(z); }
管程:
管程也是用于临界区的一种方法,它的操作过程就是,考虑到了当前线程因为一些原因等待时候的情况,这个时候就先放弃临界区的锁,给别的进程先执行,在里面设置有等待队列
Wait():将自己加入等待队列种,然后唤醒一个等待者或者释放管程的互斥访问
Signal(): 将等待队列中的一个线程唤醒
管程形式的生产者-消费者问题
Lock lock int count=0 int x,y //代表东西数和空间数 product(){ lock-Acquire() ; while(count==n){ notFull.wait(&lock) //把自己加入等待队列 } Add c to the buffer; count++ notEmpty.Signal(); lock->release } cutomer(){ lock->Acquire() while(count==0) notEmpty.Wait(&lock); remove c from buffer count-- notFull.Signal lock->Release() }
哲学家就餐
要求:哲学家就餐也就是n个人n把叉围成一圈,每个人左右两边分别有把叉,然后哲学家每个都能做两件事,思考和就餐,就餐必须拿自己左右两边的叉子才能就餐,怎么有序执行下去
这里明显叉子就是互斥信号量
信号量做法
int cha[5] //5把叉子 while(1){ think()//哲学家在思考 P(cha[i]); P(cha[i+1]) eat() //就餐 V(cha[i]); V(cha[i+1]) } //如果每个哲学家同时动手拿左边叉子,然后都得不到右边,又无法释放资源,那么处于死锁 while(1){ think()//哲学家在思考 P(flag) // 临界区 P(cha[i]); P(cha[i+1]) eat() //就餐 V(cha[i]); V(cha[i+1]) V(flag); } //这种方法虽然可以,但是加了临界区之后,明明5个人可以同时两个用餐,但是这样变成了一次只能有一个人 while(1){ think()//哲学家在思考 if(i%2==0){ P(cha[i]); P(cha[i+1]) } else{ P(cha[i+1]); P(cha[i]); } eat() //就餐 V(cha[i]); V(cha[i+1]) } 因为第一种方案的死锁只是在都拿左边的时候才会出现,所以只要控制不同人拿的方向不一样就不会出现这种情况了
读者-写者
要求:读者能够同时有多个进行访问,写只能一个人进行写,读写不能同时进行
死锁概念:
死锁就是进程都处于在申请资源的状态,并且自己也持有对方要的资源
死锁四个必要条件:四个同时成立才会发生死锁
1,互斥:这些资源必须是互斥的,同时只能有一个能够访问
2,请求并保持:自己有资源而且处于申请资源的状态
3,非抢占:只能进程自己运行完自己主动释放资源不能够抢夺
4,循环等待:构成一个环 A->B->C->A 申请的资源都在对方这里
死锁处理
死锁预防: 构成死锁的四个必要条件,只要把其中一个破坏,那么就会预防掉死锁,所以有四种办法
死锁避免:如果当前分配资源会发生死锁,那么申请的资源不会得到分配,然后可以通过银行家算法得出安全序列
死锁检测和恢复