进程

进程的定义

  • 进程是程序的一次执行。
  • 进程是一个程序及其数据在处理机上执行所发生的的活动。
  • 进程是一个程序在数据集上运行的过程,它是系统进行资源分配和调度的独立单位。

进程的三种基本状态

在这里插入图片描述

引起进程创建的事件

  • 用户登录
  • 作业调度
  • 提供服务
  • 应用请求

进程的创建

  • 申请空白PCB
  • 为新进程分配空间
  • 初始化PCB
  • 将新进程插入就绪队列

进程的终止

  • 从PCB队列中读出进程
  • 终止进程的执行,将处理机分配给其他进程
  • 终止其子孙进程
  • 回收所有资源
  • 从队列删除PCB

进程同步

临界资源

OS 把同一时间只能为一个进程访问的资源成为临界资源。

临界区

进程中访问临界资源的那段代码称为临界区。

同步机制应遵循的规则

  • 空闲让进
  • 忙则等待
  • 让权等待
  • 有限等待

信号量机制

整型信号量

最初由Dijkstra 把整型信号量定义成一个整型量,除初始化外仅能通过两个原子操作wait(s)、signal(s)来访问。

wait(s){
     while(s<=0){}
     s--;
}
signal(s){
         s++;
}

记录型信号量

在整型信号量中,S<=0,需要不断测试,处于‘忙等’状态,因为违背了‘让权等待’的准则。在满足让权等待的前提下,多个进程有可能竞争统一临界资源的情况,因此必须有一个资源数目的变量和一个等待链表。为此为原有信号量作以下定义:

type semaphore{
  value : Integer,
  L :list of process 
}
wait(s){
          s.value = s.value -1;
          if(s.value <0) {
          block(s,L);
          }
}
signal(s){
       s.value = s.value +1;
       if(s.value <=0){
       wakeup(s,L);
       }
}

AND 型信号量

上述进程互斥问题只针对进程之间互斥共享一个资源而言,但有些场景下,一个进程需要获得两个或更多的资源后才能继续执行。所以要保证进程之间同步,就引入了AND型信号量即一次申请进程执行所需的所有资源。

Swait(s1,s2,s3...)
Ssingal(s1,s2,s3...)

信号量的应用

利用信号量实现进程互斥
  • 某交通路口设置了一个自动计数系统,该系统由“观察者”进程和“报告者”进程组成。观察者进程能识别卡车,并对通过的卡车计数;报告者进程定时(可设为每隔1小时,准点时)将观察者的计数值打印输出,每次打印后把计数值清“0”。两个进程的并发执行可完成对每小时中卡车流量的统计。这两个进程的功能如下
Semaphore S ;
int count =0;
S.value =1;
process observer(){
     while(Condition){
       observe a lorry;
       wait(S);
       count++;
       signal(S);
    }
}
process reporter(){
    wait(S);
    print(count);
    count =0;
    signal(S);
}
利用记录型信号量解决生产者消费者问题

假定在生产者和消费者之间的公用缓冲池中,具有n个缓冲区,这时可利用互斥信号量mutex实现诸进程对缓冲池的互斥使用;利用信号量empty和full分别表示缓冲池中空缓冲区和满缓冲区的数量。又假定这些生产者和消费者相互等效,只要缓冲池未满,生产者便可将消息送入缓冲池;只要缓冲池未空,消费者便可从缓冲池中取走一个消息。对生产者—消费者问题可描述如下:

Semaphore mutex=1;
Semaphore empty=n;
Semaphore full =0;
Queue queue = new Queue(n);

procedurer(e){
    wait(empty);
    wait(mutex);
    queue.offer(e);
    signal(mutex);
    sugnal(full);
}

consumer(){
    wait(full);
    wait(mutex);
    queue.poll();
    signal(mutex);
    signal(empty);
}
利用AND型信号量解决生产者消费者问题
Semaphore mutex=1;
Semaphore empty=n;
Semaphore full =0;
Queue queue = new Queue(n);

procedurer(e){
    Swait(empty,mutex);
    queue.offer(e);
    Ssignal(mutex,full);
}

consumer(){
    Swait(full,mutex);
    queue.poll();
    Ssignal(mutex,empty);
哲学家进餐问题
  • 至多允许4个哲学家同时取左边的筷子,这样能至少保证一个哲学家能就餐,并在用毕后释放他用过的两只筷子,从而使更多的哲学家能够进餐。(请学生考虑算法的描述)
  • 仅当哲学家左右两只筷子均可用时,才允许他拿起筷子进餐。(用AND信号量机制)
  • 规定奇数号哲学家先拿左边筷子,然后再拿右边筷子;而偶数号哲学家先拿右边筷子,然后再拿左边筷子。

进程间通信

共享内存

消息传递系统

直接通信

这是指发送进程利用OS所提供的发送命令,直接把消息发送给目标进程。此时,要求发送进程和接收进程都以显式方式提供对方的标识符。通常,系统提供下述两条通信命令(原语):
Send(Receiver, message); 发送一个消息给接收进程;
Receive(Sender, message); 接收Sender发来的消息;

间接通信

信箱通信

管道通信

所谓管道是指连接一个读进程和一个写进程并实现通信的共享文件,又称为pipe文件,以字符流的方式交换信息。主要解决下面三个问题:

  • 互斥
  • 同步
  • 对方是否存在

线程

线程的定义

  • 轻型实体
  • 独立调度和分派的基本单位
  • 可并发执行
  • 共享进程资源

线程的分类

  • 内核级线程
    无论是用户进程中的线程,还是系统进程中的线程,它们的创建、撤消和切换等,都是依靠内核实现的。此外,在内核空间为每一个内核支持线程设置了一个线程控制块, 内核是根据该控制块而感知某线程的存在的,并对其加以控制。
  • 用户线程
    用户级线程仅存在于用户空间中。这种线程的创建、 撤消、线程之间的同步与通信等功能,都无须利用系统调用来实现。对于用户级线程的切换,通常是发生在一个应用进程的诸多线程之间,无须内核的支持。
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值