操作系统学习记录之十:进程与线程的总结

是看了很多优秀的博客总结在一起的,下面是原博地址:

https://www.cnblogs.com/shilinnpu/p/8873390.html

https://blog.csdn.net/fly_yr/article/details/50970198

https://blog.csdn.net/return_true_hang/article/details/69665231

https://www.cnblogs.com/tomato0906/articles/7748134.html

1.进程和线程的区别

比较通俗的解释:

一个系统运行着很多进程,可以比喻为一条马路上有很多马车,不同的进程可以理解为不同的马车;

而同一辆马车可以有很多匹马来拉--这些马就是线程;

假设道路的宽度恰好可以通过一辆马车,道路可以认为是临界资源;

那么马车成为分配资源的最小单位(进程);

而同一个马车被很多匹马驱动(线程)--即最小的运行单位;

每辆马车马匹数=1,所以马匹数=1的时候进程和线程没有严格界限,只存在一个概念上的区分度;

马匹数是否为1才可以严格区分进程和线程;

专业解释:

简而言之,一个程序至少有一个进程,一个进程至少有一个线程.

线程的划分尺度小于进程,使得多线程程序的并发性高。另外,进程在执行过程中拥有独立的内存单元,而多个线程共享一个进程的内存,从而极大地提高了程序的运行效率。

线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。

进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.

线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.

进 程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个 进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序 健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。

引入线程的原因:

(1)易于调度。

(2)提高并发性。通过线程可方便有效地实现并发性。进程可创建多个线程来执行同一程序的不同部分。

(3)开销少。创建线程比创建进程要快,所需开销很少。

(4)利于充分发挥多处理器的功能。通过创建多线程进程(即一个进程可具有两个或更多个线程),每个线程在一个处理器上运行,从而实现应用程序的并发性,使每个处理器都得到充分运行。

2.进程间的通信方式

    因为多进程中每个进程有自己的地址空间,线程则共享地址空间,实际上只有进程间需要通信,同一进程的线程共享地址空间,没有通信的必要,但要做好同步/互斥,保护共享的全局变量。

而进程间通信无论是信号,管道pipe还是共享内存都是由操作系统保证的,是系统调用. 

信号--用于进程同步与互斥:

       信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。信号是进程间通信机制中唯一的异步通信机制,可以看作是异步通知,通知接收信号的进程有哪些事情发生了。信号机制经过POSIX实时扩展后,功能更加强大,除了基本通知功能外,还可以传递附加信息。信号事件的发生有两个来源:硬件来源(比如我们按下了键盘或者其它硬件故障);软件来源。

信号分为可靠信号和不可靠信号,实时信号和非实时信号。

进程有三种方式响应信号:

  • 忽略信号
  • 捕捉信号
  • 执行缺省操作

信号量--用于进程同步与互斥:

       信号量也可以说是一个计数器,常用来处理进程或线程同步的问题,特别是对临界资源的访问同步问题。临界资源:为某一时刻只能由一个进程或线程操作的资源,当信号量的值大于或等于0时,表示可以供并发进程访问的临界资源数,当小于0时,表示正在等待使用临界资源的进程数。更重要的是,信号量的值仅能由PV操作来改变。

消息队列--用于传递消息:

      消息队列是消息的链接表,它克服了上两种通信方式中信号量有限的缺点,具有写权限得进程可以按照一定得规则向消息队列中添加新信息;对消息队列有读权限得进程则可以从消息队列中读取信息。

共享内存:

      共享内存就是分配一块能被其他进程访问的内存。共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式。在使用共享内存区前,必须通过系统函数将其附加到进程的地址空间或说为映射到进程空间。两个不同进程A、B共享内存的意思是,同一块物理内存被映射到 进程A、B各自的进程地址空间。进程A可以即时看到进程B对共享内存中数据的更新,反之亦然。由于多个进程共享同一块内存区域,必然需要某种同步机制,互 斥锁和信号量都可以。采用共享内存通信的一个显而易 见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝。对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而 共享内存则只拷贝两次数据:一次从输入文件到共享内存区,另一次从共享内存区到输出文件。实际上,进程之间在共享内存时,并不总是读写少量数据后就 解除映射,有新的通信时,再重新建立共享内存区域。而是保持共享区域,直到通信完毕为止,这样,数据内容一直保存在共享内存中,并没有写回文件。共享内存 中的内容往往是在解除映射时才写回文件的。因此,采用共享内存的通信方式效率是非常高的。

管道--用于传递消息:

      管道传递数据是单向性的,只能从一方流向另一方,也就是一种半双工的通信方式;只用于父子进程或兄弟进程;没有名字并且大小受限,传输的是无格式的流,所以两进程通信时必须约定好数据通信的格式。管道它就像一个特殊的文件,但这个文件之存在于内存中,在创建管道时,系统为管道分配了一个页面作为数据缓冲区,进程对这个数据缓冲区进行读写,以此来完成通信。其中一个进程只能读一个只能写,所以叫半双工通信,写进程是在缓冲区的末尾写入,读进程是在缓冲区的头部读取,他们各自 的数据结构不同,所以功能不同。

有名管道--用于传递消息:

       命名管道(NamedPipe)是服务器进程和一个或多个客户进程之间通信的单向或双向管道。不同于匿名管道的是:命名管道可以在不相关的进程之间和不同计算机之间使用,服务器建立命名管道时给它指定一个名字,任何进程都可以通过该名字打开管道的另一端,根据给定的权限和服务器进程通信。命名管道提供了相对简单的编程接口,使通过网络传输数据并不比同一计算机上两进程之间通信更困难,不过如果要同时和多个进程通信它就力不从心了。

命名管道不同与管道只能在具有亲缘关系的进程间通信了。它提供了一个路径名与之关联,有了自己的传输格式。

命名管道和管道的不同之处还有一点是,有名管道是个设备文件,存储在文件系统中,没有亲缘关系的进程也可以访问,但是它要按照先进先出的原则读取数据,同样也是单双工的

套接字(IP地址加端口号)--用于交换数据:

   可用于不同主机之间的通信;

3.线程间的通信方式

        由于多线程共享地址空间和数据空间,所以多个线程间的通信是一个线程的数据可以直接提供给其他线程使用,而不必通过操作系统(也就是内核的调度)。线程间的通信目的主要是用于线程同步,所以线程没有像进程通信中的用于数据交换的通信机制。

锁机制:

包括互斥锁、条件变量、读写锁;

 互斥锁提供了以排他方式防止数据结构被并发修改的方法。

使用条件变量可以以原子的方式(要么全部发生要么不发生)阻塞进程,直到某个特定条件为真为止。对条件的测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用。
读写锁允许多个线程同时读共享数据,而对写操作是互斥的。

信号量机制:

       包括无名线程信号量和命名线程信号量 

信号机制:

       类似进程间的信号处理;

4.线程的同步方式

    临界区(Critical Section)、互斥量(Mutex)、信号量(Semaphore)、事件(Event)四种方式

临界区:

      通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。在任意时刻只允许一个线程对共享资源进行访问,如果有多个线程试图访问公共资源,那么在有一个线程进入后,其他试图访问公共资源的线程将被挂起,并一直等到进入临界区的线程离开,临界区在被释放后,其他线程才可以抢占

互斥量:

      采用互斥对象机制。 只有拥有互斥对象的线程才有访问公共资源的权限,因为互斥对象只有一个,所以能保证公共资源不会同时被多个线程访问。互斥不仅能实现同一应用程序的公共资源安全共享,还能实现不同应用程序的公共资源安全共享 .互斥量比临界区复杂。因为使用互斥不仅仅能够在同一应用程序不同线程中实现资源的安全共享,而且可以在不同应用程序的线程之间实现对资源的安全共享。

信号量:

       它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目 .这与操作系统中的PV操作相同。它指出了同时访问共享资源的线程最大数目。

    PV操作及信号量的概念都是由荷兰科学家E.W.Dijkstra提出的。信号量S是一个整数,S大于等于零时代表可供并发进程使用的资源实体数,但S小于零时则表示正在等待使用共享资源。
   P操作申请资源:
  (1)S减1;
  (2)若S减1后仍大于等于零,则进程继续执行;
  (3)若S减1后小于零,则该进程被阻塞后进入与该信号相对应的队列中,然后转入进程调度。  
  V操作 释放资源:
  (1)S加1;
  (2)若相加结果大于零,则进程继续执行;
  (3)若相加结果小于等于零,则从该信号的等待队列中唤醒一个等待进程,然后再返回原进程继续执行或转入进程调度。

事件:

        通过通知操作的方式来保持线程的同步,还可以方便实现对多个线程的优先级比较的操作 . 事件分为手动置位事件和自动置位事件。事件Event内部它包含一个使用计数(所有内核对象都有),一个布尔值表示是手动置位事件还是自动置位事件,另一个布尔值用来表示事件有无触发。由SetEvent()来触发,由ResetEvent()来设成未触发。

5.同步和互斥的区别(线程/进程)

       进程互斥:指若干个进程要使用同一共享资源时,任何时刻最多允许一个进程去使用,其他要使用该资源的进程必须等待,直到占有资源的进程释放该资源。 
       进程的同步:是解决进程间协作关系( 直接制约关系) 的手段。进程同步指两个以上进程基于某个条件来协调它们的活动。一个进程的执行依赖于另一个协作进程的消息或信号,当一个进程没有得到来自于另一个进程的消息或信号时则需等待,直到消息或信号到达才被唤醒 ;

      所 谓互斥,是指散布在不同进程之间的若干程序片断,当某个进程运行其中一个程序片段时,其它进程就不能运行它们之中的任一程序片段,只能等到该进程运行完这 个程序片段后才可以运行。如果用对资源的访问来定义的话,互斥某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资 源的访问顺序,即访问是无序的

      所谓同步,是指散步在不同进程之间的若干程序片断,它们的运行必须严格按照规定的某种先后次序来运行,这种先后次序依赖于要完成的特定的任务。如果用对资源的访问来定义的话,同步是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源;

综上:进程互斥、同步与通信的关系:同步是一种特殊的互斥,进程互斥是一种进程通信,由此看来,进程互斥、同步都可以看做进程的通信;

猜你喜欢

转载自blog.csdn.net/cxy19931018/article/details/81503320