操作系统总结之进程

    技术2022-05-13  26

    这学期学了门操作系统,看到大家上课后感觉很困难,所以想整理点东西帮助大家总结。

    进程:a program in execution从前:单进程现在:多进程即通过CPU的多路复用使得同时执行多个进程。

    进程分为用户进程和系统进程。在进程之前,其实作业才是第一个被提出来的,用于批处理系统中。批处理系统术语:提交作业。分时系统术语:任务。任务和作业都类似于进程。只是称呼不同罢了。

    进程包括了许多东西,在内存中一个进程有文本段(放代码的地方)、数据(放全局变量)、堆(动态分配的数据,堆是向上伸展)、栈(局部变量、函数参数,栈是向下伸展的)。进程和程序的区别:程序(exe)、进程是活动的即包含PC。当程序被load进memory时,就成了进程。当多个进程与一个程序相关时,他们是单独的进程,共享文本段,栈、堆等各自独立。

    进程在OS中状态想像成一张图,new、running、ready、waiting、terminate.

    waiting状态是指进程要执行I/O,则被调入I/O设备的等待队列等待。

    ready则是在内存中的就绪队列中。但是记住一个处理器只能running一个进程,但是能有多个进程在等待和就绪队列中。

    就绪队列听名字就很形象,不多说了。要说的是他在内存中。每个device都有一个队设备列,链表存放。进程在OS中以PCB方式存在。再讲下PCB的结构,PCB很复杂,但是能够实现很多功能,不必全部死记硬背。(0)pid

    (1)进程状态。(2)PC.指向下一个PCB。(3)CPU寄存器。存放变量,堆栈指针。(4)CPU调度信息。PCB的优先级,调度指针。(5)内存管理信息:base&limit寄存器,页表段表。(6)记账信息。用的时间,用了多少内存等等。(7)I/O状态。对应I/O设备的状态。打开的文件。

    multiprogramming通过一个程序接一个程序的执行,把最宝贵的CPU时间填满。timesharing通过把一个CPU时间分成时间片,平均分给用户,与用户交互,使得用户感觉像一个人单独用机器.

    linux 是以C的struct来实现PCB的。

     

    进程进入CPU后可能会有4种情况:

    1.I/O请求进入设备队列。

    2.产生子进程而进入就绪队列。

    3.发生中断被迫停止。

    4.顺利执行完。

     

    批处理系统中,进程被放入磁盘的缓冲池中,当需要被用到时,就导入内存,这个成为长期调度程序。可以控制多道程序的degree(你想哦,多道程序的特点是一次导入多个进程进入内存,目的是将CPU的时间塞满。)从内存中选择进程导入CPU的程序称为短期调度程序,频繁执行。

    进程分为:I/O为主(大多数PCB都是在设备队列中),CPU为主(大多数PCB用于执行计算)。长期调度需要选择合理的组合进内存。UNIX/Windows没有长期调度程序。直接把进程放入内存,但是会出现灾难,所以引入了medium-term schedular。分时系统中,引入了中期调度程序:可以将某些进程从内存中移出,到某时可以再导入,从中断处继续执行,这个也称为swapping。

    上下文切换:就是PCB的保存与恢复。保存旧进程的PCB,并放入新进程。如果是多组寄存器集合,则可以一些寄存器保存一个进程的状态,那么上下文切换可以简单地改变寄存器的指针即可。

    进程树:一个进程在执行时能创建新的进程,新的进程又能再创建新的进程,形成了进程树。pid用来标识每个进程。子进程可以共享父进程的资源也可以从OS那拿资源。但是共享父进程资源能够限制资源的分配。父进程与子进程可以并发执行也可以先执行子进程再执行父进程。

    UNIX中(1)fork()创建进程,子进程调用时返回0,父进程返回子进程的pid。(2)exec():执行。(3)wait():父进程等待。(4)exit():退出。

    进程执行exit ()后就终止了,并释放资源。

    子进程终止后,pid要返回给父进程,父进程就知道哪个子进程结束了。父进程可以也通过系统调用终止子进程。

    级联终止:父进程终止导致子进程被迫终止。

    进程分为独立的和协作的。协作进程在后面进程同步时会提到。

    进程通信IPC1.共享内存。传输速度快,只在创建共享区域时使用系统调用,其余时刻都是正常的内存访问。

    2.消息传递。用于交换较少数据。通过send和receive来发送和接受消息,这样就不必共享内存。两者的数据格式都没有严格规定。

    有限缓冲:缓冲的大小固定。

    无限缓冲:缓冲的大小无限。

    共享内存用于解决生产者消费者模型的问题,需循环队列缓冲,加入变量count可以解决缓冲项数只有BUFFER_SIZE-1的问题。服务器代码:while(true){ while((in+1)%BUFFER_SIZE==out); buffer[in]=new; in=(in+1)%BUFFER_SIZE; }客户端代码:while(true){ while(in==out); new=buffer[out]; out=(out+1)%BUFFER_SIZE;}

    消息传递,有OS提供,分布式环境中。如果要使两个进程进行消息传递,必须要有通信线路。直接通信:send和receive的参数直接说明接受者和发送者的对象名,只要调用函数,则自动创建链路,并且一个线路只能有两个进程。间接通信:通过第三方(邮箱)为暂存。两个进程之间可以有多条线路(即多个邮箱)。一个邮箱可以有多个进程共享。邮箱挺像共享内存。对于send和receive的执行方法(面对模棱两可时),通过算法实现,没有特定要求。

    邮箱的拥有者:

    1.进程。则要确定拥有者和使用者。邮箱存在进程的地址空间中,当进程终止,则邮箱也终止。2.OS。不属于特定进程。创建新邮箱的进程默认为邮箱的拥有者。

    阻塞某功能:某功能一执行,就不能再执行该功能。非阻塞某功能:相反。

    消息传递缓冲队列:1.0容量。2.有限。3.无限。

    /*---------------------------------------------------------------------------------------------------------------

    在定义通信的时候,有没有想过就算知道对象,但是是怎么确定线路,最后找到目标的呢。?命名问题也比较重要。1.broadcasting2.forward pointer  多级搜索3.home-based approach  (1)one-tiered scheme:每次查找都通过home的集中营去找(2)two-tiered scheme:先在本地找,如果找不到,则在home中找。4.distributed hash tables:chord system . 用环状的hash表。但是不能保证原有的物理位置。name resolution:根据name 找到address。Name linking:hard link或者soft link。namespace的实现:hierarchy

    -------------------------------------------------------------------------------------------------------------------*/来讲客户服务器模型的另外3种通信方法。

    1.socket。socket是成对出现的。一个socket是ip地址+端口号组成。服务器始终监听各个端口号,当客户发出请求时,他会与服务器监听的端口号相匹配进行通信。但是Socket只允许交换的是无结构的字节流。RMI就可以通过实现序列化--------------------------------------------------------------------------------------------------------------------------

    java提供了Socket类

    Socket类实现TCPsocket;DatagramSocket类实现UDPsocket;socket还可以多播发送。

    import java.net.*;import java.io.*;

    public class DataServer{ public static void main(String[]args) {  try{   ServerSocket sock=new ServerSocket(6013);   while(true)   {    Socket client=sock.accept();    PrintWriter pout=new PrintWriter(client.getOutputStream(),true);    pout.println(new java.util.Data.toString());    client.close();   }  }  catch(Exception e)  {   System.err.println(e);  } }}

    PrintWriter能够使服务器能直接利用println发送给客户。

    import java.net.*;import java.io.*;public class DataClient{ public static void main(String[]args) {  try  {   sock=new Socket("127.0.0.1",6013);   inputStream in=sock.getInputStream();   BufferReader bin=new BufferReader(new InputStreamReader(in));   String line;   while((line=bin.readLine())!=NULL)   {    System.out.println(line);   }   sock.close();  }  catch(Exception e)  {   System.err.println(e);  } }}

    --------------------------------------------------------------------------------------------------------------------------2.RPC数据有很好的结构。客户发出要执行的函数,在服务器端执行完后,把结果返回给客户。RPC的目的是为了让客户调用服务器像调用本地一样。存根只是一个接口。XDR(外部数据表示):用来统一客户端和服务器的数据表示形式。必须确保RPC数据传送的唯一性。即只能传一次(ack解决)对于绑定服务与客户,有两种方法:第一种是端口固定。第二种是通过集合点来绑定(先访问集合点请求端口号,再等待返回端口号)。3.RMI   java中的RPC如果对象位于不同的JVM,则称为远程。因此可以在一台机器开多个JVM进行模拟通信,打开一个命令行就说明打开一个JVM。

    客户端保留存根(远程方法的接口),本地参数可以是任何继承了java.io.serializable的接口类。注意,远程对象都要继承remote类,每个远程方法要throws remoteException。只有远程方法才能引用。RMI VS RPC1.RMI的数据结构是对象,调用远程的对象方法。RPC支持子程序编程。2.RMI的参数是对象,RPC是普通的数据结构。

    RMI采用存根(在客户机)和骨干(服务器)。其实骨干就是存根。     


    最新回复(0)