精华内容
下载资源
问答
  • 这两天看进程的同步与通信,看了几本书上的介绍,也从网上搜了很多资料,越看越迷惑,被这几个问题搞得很纠结。进程同步与互斥的区别?进程的同步方式有哪些?进程的通信方式有哪些?进程同步与通信的区别是什么?...

    这两天看进程的同步与通信,看了几本书上的介绍,也从网上搜了很多资料,越看越迷惑,被这几个问题搞得很纠结。

    1. 进程同步与互斥的区别?
    2. 进程的同步方式有哪些?
    3. 进程的通信方式有哪些?
    4. 进程同步与通信的区别是什么?
    5. 线程的同步/通信与进程的同步/通信有区别吗?

    在好多教材上(包括国内与国外的)也没有明确这些概念,现在对每个问题还没有准确的答案,下面将自己的理解记下来,以后再补充。

    参考资料:

    《操作系统教程》 孙钟秀主编 费翔林  骆斌  谢立参编 高等教育出版社

    《计算机操作系统》 何炎祥 李飞 李宁 编著 清华大学出版社(进程管理部分与《操作系统教程》中的类似)

    进程互斥、同步的概念

    进程互斥、同步的概念是并发进程下存在的概念,有了并发进程,就产生了资源的竞争与协作,从而就要通过进程的互斥、同步、通信来解决资源的竞争与协作问题。

    下面是根据《操作系统教程》3.1.4 中的介绍,整理的进程互斥、同步的概念。

    在多道程序设计系统中,同一时刻可能有许多进程,这些进程之间存在两种基本关系:竞争关系和协作关系。

    进程的互斥、同步、通信都是基于这两种基本关系而存在的。

    为了解决进程间竞争关系(间接制约关系)而引入进程互斥;

    为了解决进程间松散的协作关系( 直接制约关系)而引入进程同步;

    为了解决进程间紧密的协作关系而引入进程通信。

    第一种是竞争关系 

    系统中的多个进程之间彼此无关,它们并不知道其他进程的存在,并且也不受其他进程执行的影响。例如,批处理系统中建立的多个用户进程, 分时系统中建立的多个终端进程。由于这些进程共用了一套计算机系统资源,因而, 必然要出现多个进程竞争资源的问题。当多个进程竞争共享硬设备、存储器、处理器 和文件等资源时,操作系统必须协调好进程对资源的争用。

    资源竞争出现了两个控制问题:

    一个是死锁 (deadlock )问题,一组进程如果都获得了部分资源,还想要得到其他进程所占有的资源,最终所有的进程将陷入死锁。

    另一个是饥饿(starvation )问题,这是指这样一种情况:一个进程由于其他进程总是优先于它而被无限期拖延。

    操作系统需要保证诸进程能互斥地访问临界资源,既要解决饥饿问题,又要解决死锁问题。 
        进程的互斥(mutual exclusion )是解决进程间竞争关系( 间接制约关系) 的手段。 进程互斥指若干个进程要使用同一共享资源时,任何时刻最多允许一个进程去使用,其他要使用该资源的进程必须等待,直到占有资源的进程释放该资源。

    第二种是协作关系          

    某些进程为完成同一任务需要分工协作,由于合作的每一个进程都是独立地以不可预知的速度推进,这就需要相互协作的进程在某些协调点上协 调各自的工作。当合作进程中的一个到达协调点后,在尚未得到其伙伴进程发来的消息或信号之前应阻塞自己,直到其他合作进程发来协调信号或消息后方被唤醒并继续执行。这种协作进程之间相互等待对方消息或信号的协调关系称为进程同步

    进程间的协作可以是双方不知道对方名字的间接协作,例如,通过共享访问一个缓冲区进行松散式协作;也可以是双方知道对方名字,直接通过通信机制进行紧密协作。允许进程协同工作有利于共享信息、有利于加快计算速度、有利于实现模块化程序设计。

    进程的同步(Synchronization)是解决进程间协作关系( 直接制约关系) 的手段。

    进程同步指两个以上进程基于某个条件来协调它们的活动。一个进程的执行依赖于另一个协作进程的消息或信号,当一个进程没有得到来自于另一个进程的消息或信号时则需等待,直到消息或信号到达才被唤醒。

    不难看出,进程互斥关系是一种特殊的进程同步关系,即逐次使用互斥共享资源,也是对进程使用资源次序上的一种协调。

    进程通信的概念

    下面是根据《操作系统教程》3.5 中的介绍,整理的进程通信的概念。

    并发进程之间的交互必须满足两个基本要求:同步和通信。

    进程竞争资源时要实施互斥,互斥是一种特殊的同步,实质上需要解决好进程同步问题,进程同步是一种进程通信,通过修改信号量,进程之间可建立起联系,相互协调运行和协同工作。但是信号量与PV操作只能传递信号,没有传递数据的能力。有些情况下进程之间交换的信息量虽很少,例如,仅仅交换某个状态信息,但很多情况下进程之间需要交换大批数据,例如,传送一批信息或整个文件,这可以通过一种新的通信机制来完成,进程之间互相交换信息的工作称之为进程通信IPC (InterProcess Communication)(主要是指大量数据的交换)。

    进程间通信的方式很多,包括: 

    1 mmap(文件映射)

    2 信号

    3 管道

    4 共享内存

    5 消息队列(重要)

    6 信号量集(与signal无关)

    7 网络(套接字)

    进程同步的方法

    前面提到,进程互斥关系是一种特殊的进程同步关系,下面给出常见的进程同步的方法,实际上也可用于进程的互斥(个人理解)。

     Linux 下常见的进程同步方法有:

     1、信号量

     2、管程

     3、 互斥量(基于共享内存的快速用户态 

     4、文件锁(通过 fcntl 设定,针对文件)

     针对线程(pthread)的还有 pthread_mutex 和 pthread_cond(条件变量)。

    线程的同步方法:

    1、信号量

    2、互斥量

    3、临界区

    4、事件

     同步机制:

    四种进程或线程同步互斥的控制方法
    1、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。 
    2、互斥量:为协调共同对一个共享资源的单独访问而设计的。 
    3、信号量:为控制一个具有有限数量用户资源而设计。 
    4、事 件:用来通知线程有一些事件已发生,从而启动后继任务的开始。

     科普:

    1.临界资源

      临界资源是一次仅允许一个进程使用的共享资源。各进程采取互斥的方式,实现共享的资源称作临界资源。属于临界资源的硬件有,打印机,磁带机等;软件有消息队列,变量,数组,缓冲区等。诸进程间采取互斥方式,实现对这种资源的共享。


    2.临界区:

      每个进程中访问临界资源的那段代码称为临界区criticalsection),每次只允许一个进程进入临界区,进入后,不允许其他进程进入。不论是硬件临界资源还是软件临界资源,多个进程必须互斥的对它进行访问。多个进程涉及到同一个临界资源的的临界区称为相关临界区使用临界区时,一般不允许其运行时间过长,只要运行在临界区的线程还没有离开,其他所有进入此临界区的线程都会被挂起而进入等待状态,并在一定程度上影响程序的运行性能。

    临界区是一种轻量级的同步机制,与互斥和事件这些内核同步对象相比,临界区是用户态下的对象,即只能在同一进程中实现线程互斥。因无需在用户态和核心态之间切换,所以工作效率比较互斥来说要高很多。虽然临界区同步速度很快,但却只能用来同步本 进程内的线程,而不可用来同步多个进程中的线程。

      
    临界区(Critical Section)


    保证在某一时刻只有一个线程能访问数据的简便办法。在任意时刻只允许一个线程对共享资源进行访问。如果有多个线程试图同时访问临界区,那么 在有一个线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操 作共享资源的目的。 
    临界区包含两个操作原语: 
    EnterCriticalSection() 进入临界区 
    LeaveCriticalSection() 离开临界区 
    EnterCriticalSection() 语句执行后代码将进入临界区以后无论发生什么,必须确保与之匹配的 LeaveCriticalSection()都能够被执行到。否则临界区保护的共享资源将永远不会被释放。虽然临界区同步速度很快,但却只能用来同步本 进程内的线程,而不可用来同步多个进程中的线程。 
    MFC提供了很多功能完备的类,我用MFC实现了临界区。MFC为临界区提供有一个 CCriticalSection类,使用该类进行线程同步处理是 非常简单的。只需在线程函数中用CCriticalSection类成员函数Lock()和UnLock()标定出被保护代码片段即可。Lock()后代 码用到的资源自动被视为临界区内的资源被保护。UnLock后别的线程才能访问这些资源。

    互斥量(Mutex) 
       
    互斥量跟临界区很相似,只有拥有互斥对象的线程才具有访问资源的权限,由于互斥对象只有一个,因此就决定了任何情况下此共享资源都不会同时被多个线程所访问。当前占据资源的线程在任务处理完后应将拥有的互斥对象交出,以便其他线程在获得后得以访问资源。互斥量比临界区复杂。因为使用互斥不仅仅能够在同一应用程序不同线程中实现资源的安全共享,而且可以在不同应用程序的线程之间实现对资源的安全共享。 
       
    互斥量包含的几个操作原语: 
    CreateMutex() 创建一个互斥量 
    OpenMutex() 打开一个互斥量 
    ReleaseMutex() 释放互斥量 
    WaitForMultipleObjects() 等待互斥量对象 

    信号量(Semaphores)


    信号量对象对线程的同步方式与前面几种方法不同,信号允许多个线程同时使用共享资源 ,这与操作系统中的PV操作相同。它指出了同时访问共享 资源的线程 最大数目。它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。在用CreateSemaphore()创建信号量 时即要同时指出允许的最大资源计数和当前可用资源计数。一般是将当前可用资源计数设置为最大资源计数,每增加一个线程对共享资源的访问,当前可用资源计数 就会减1,只要当前可用资源计数是大于0的,就可以发出信号量信号。但是当前可用计数减小到0时则说明当前占用资源的线程数已经达到了所允许的最大数目, 不能在允许其他线程的进入,此时的信号量信号将无法发出。线程在处理完共享资源后,应在离开的同时通过ReleaseSemaphore()函数将当前可 用资源计数加1。在任何时候当前可用资源计数决不可能大于最大资源计数。 
    PV操作及信号量的概念都是由荷兰科学家E.W.Dijkstra提出的。信号量S是一个整数,S大于等于零时代表可供并发进程使用的资源实体数,但S小于零时则表示正在等待使用共享资源的进程数。 
    P操作 申请资源: 
         (1)S减1; 
         (2)若S减1后仍大于等于零,则进程继续执行; 
         (3)若S减1后小于零,则该进程被阻塞后进入与该信号相对应的队列中,然后转入进程调度。 
       V操作 释放资源: 
         (1)S加1; 
         (2)若相加结果大于零,则进程继续执行; 
         (3)若相加结果小于等于零,则从该信号的等待队列中唤醒一个等待进程,然后再返回原进程继续执行或转入进程调度。 
       
         信号量包含的几个操作原语: 
         CreateSemaphore() 创建一个信号量 
         OpenSemaphore() 打开一个信号量 
         ReleaseSemaphore() 释放信号量 
         WaitForSingleObject() 等待信号量

    事件(Event) 
       
    事件对象也可以通过通知操作的方式来保持线程的同步。并且可以实现不同进程中的线程同步操作。 
    信号量包含的几个操作原语: 
         CreateEvent() 创建一个事件 
         OpenEvent() 打开一个事件 
         SetEvent() 回置事件 
         WaitForSingleObject() 等待一个事件 
         WaitForMultipleObjects()         等待多个事件 
           WaitForMultipleObjects 函数原型: 
            WaitForMultipleObjects( 
            IN DWORD nCount, // 等待句柄数 
            IN CONST HANDLE *lpHandles, //指向句柄数组 
            IN BOOL bWaitAll, //是否完全等待标志 
            IN DWORD dwMilliseconds //等待时间 
            ) 
    参 数nCount指定了要等待的内核对象的数目,存放这些内核对象的数组由lpHandles来指向。fWaitAll对指定的这nCount个内核对象的两种等待方式进行了指定,为TRUE时当所有对象都被通知时函数才会返回,为FALSE则只要其中任何一个得到通知就可以返回。 dwMilliseconds在这里的作用与在WaitForSingleObject()中的作用是完全一致的。如果等待超时,函数将返回 WAIT_TIMEOUT。

     

     

     

    总结: 
    1. 互斥量与临界区的作用非常相似,但互斥量是可以命名的,也就是说它可以跨越进程使用。所以创建互斥量需要的资源更多,所以如果只为了在进程内部是用的话使用临界区会带来速度上的优势并能够减少资源占用量 。因为互斥量是跨进程的互斥量一旦被创建,就可以通过名字打开它。 
    2. 互斥量(Mutex),信号灯(Semaphore),事件(Event)都可以被跨越进程使用来进行同步数据操作,而其他的对象与数据同步操作无关,但对于进程和线程来讲,如果进程和线程在运行状态则为无信号状态,在退出后为有信号状态。所以可以使用WaitForSingleObject来等待进程和 线程退出。 
    3. 通过互斥量可以指定资源被独占的方式使用,但如果有下面一种情况通过互斥量就无法处理,比如现在一位用户购买了一份三个并发访问许可的数据库系统,可以根据用户购买的访问许可数量来决定有多少个线程/进程能同时进行数据库操作,这时候如果利用互斥量就没有办法完成这个要求,信号灯对象可以说是一种资源计数器。


    Win32 中关于进程和线程的协调工作是由同步机制来完成的,同步机制相当于线程间的红绿灯。

    一. 同步和异步

    举个例子:

    PostMessage(),是把消息放到对方的消息队列中,然后不管三七二十一,就回到原调用点继续执行,这就是异步。

    SendMessage(),就像调用一般性函数,直到调用的函数结束,才会回到原点,这就是同步行为。

    二.临界区

    如果一个线程已经进入某个临界区,则另一个线程就绝不能够进入同一个临界区。

    1. //初始化一个临界区  
    2. VOID InitializeCriticalSection(  
    3.   LPCRITICAL_SECTION lpCriticalSection  // critical section  
    4. );  
    5.   
    6. //消除一个临界区  
    7. VOID DeleteCriticalSection(  
    8.   LPCRITICAL_SECTION lpCriticalSection   // critical section  
    9. );  
    10.   
    11. //进入临界区  
    12. VOID EnterCriticalSection(  
    13.   LPCRITICAL_SECTION lpCriticalSection  // critical section  
    14. );  
    15.   
    16. //离开临界区  
    17. VOID LeaveCriticalSection(  
    18.   LPCRITICAL_SECTION lpCriticalSection   // critical section  
    19. );  
    20.   
    21. 例如:  
    22. CRITICAL_SECTION gCriticalSection;  
    23.   
    24. void Function()  
    25. {  
    26.     InitializeCriticalSection(&gCriticalSection);  
    27.   
    28.     EnterCriticalSection(&gCriticalSection);  
    29.   
    30.     //Do something here  
    31.   
    32.     LeaveCriticalSection(&gCriticalSection);  
    33.   
    34.     DeleteCriticalSection(&gCriticalSection);  
    35. }   

    一旦线程进入一个临界区,则它就可以一再的重复进入该临界区,当然每个进入操作都必须对应离开操作。

    也就是EnterCriticalSection( ),可以嵌套。

    但是千万不要在临界区中调用 sleep(),或任何 Wait..() 函数。

    临界区的缺点是:没有办法知道进入临界区中的那个线程是生是死。如果那个线程在进入临界区后当掉了,而且没有退出来,那么系统就没有办法消除掉此临界区。

    三. 互斥量

    Mutexes 用途和 Critical Section 非常类似,线程拥有 mutex 就好象线程进入 critical section 一样,但是它牺牲速度以增加弹性。

    一旦没有任何线程拥有那个 mutex,这个 mutex 便处于激发状态

    它与临界区的区别是:

    1. Mutexes 操作要比 Critical Section 费时的多。

    2. Mutexes 可以跨进程使用,Critical Section 则只能在同一进程中使用。

    3. 等待一个 Mutex 时,你可以指定"结束等待"的时间长度,而 Critical Section 则不行。

    1. HANDLE CreateMutex(  
    2.   LPSECURITY_ATTRIBUTES lpMutexAttributes,  // 安全属性,默认为NULL  
    3.   BOOL bInitialOwner,                       // initial owner  
    4.   LPCTSTR lpName                            // mutex 的名称,是一个字符串  
    5. );  
    6. //返回值:如果成功返回 handle,否则返回 NULL  
    7.   
    8. HANDLE OpenMutex(  
    9.   DWORD dwDesiredAccess,  // access  
    10.   BOOL bInheritHandle,    // inheritance option  
    11.   LPCTSTR lpName          // object name  
    12. );  
    13. //打开一个已经存在的 mutex  
    14.   
    15. BOOL ReleaseMutex(  
    16.   HANDLE hMutex   // handle to mutex  
    17. );  
    18.   
    19. //调用过程如下:  
    20. CreateMutex(); //创建  
    21. WaitForXXXObject(); //等待  
    22.   
    23. ReleaseMutex(); //释放  
    24. CloseHandle(); //关闭  

    说明:

    1. Mutex 的拥有权:

    Mutex 的拥有权并非属于那个产生它的线程,而是那个最后对些 Mutex 进行 WaitXXX() 操作并且尚未进行 ReleaseMutex() 操作的线程。

    2. Mutex 被舍弃:

    如果线程在结束前没有调用 ReleaseMutex(),比如线程调用了 EXitThread() 或者因为当掉而结束。这时的 mutex 不会被摧毁,而是被视为"未被拥有"以及"未被激发"的状态,在下一个 WaitXXX() 中线程会被以WAIT_ABANDONED_0 (WAIT_ABANDONED_0_n + 1 )来通知。

    3. 最初拥有者:

    CreateMutex(),第二个参数 bInitialOwner,允许你指定现行线程是否立刻拥有产生出来的 mutex。

    如果没有指定立刻拥有的情况:

    1. HANDLE hMutex = CreateMutex(NULL, FALSE, "Sample Name");  
    2.   
    3. int result = WaitForSingleObject(hMutex, INFINITE);  
    可能发生,在 CreateMutex 完成之后,发生了 context switch,执行权切换到另一个线程,那么其它进程就有可能在 mutex 的产生者调用 WaitForSingleObject( ) 之前,锁住这个 mutex 对象。 

    通信机制:

    管道、FIFO、消息队列、信号量、共享内存是进程的通信机制,教材上没有线程的通信机制这样的说法,但可以肯定这几种方法是进程的通信方式,且其中的信号量既可用于进程、线程的同步,又可用于进程的通信 

    管道与管程是不同的,管程是进程同步的方式,而管道则是进程通信的方式。

       

    进程通信也就是所谓的IPC问题,主要是指进程间交换数据的方式。进程通信包括高级通信与低级通信,其中进程同步与互斥属于低级通信,主要用于插U农地控制信号;高级通信包括三种:共享存储系统(有的地方称作共享内存区)、消息传递系统(有的地方称作消息队列)、管道。

    信号量是进程同步与互斥的常用方法,也可以作为低级的进程通信方法,用于传递控制信号。

    简而言之,进程间通信方式主要包括管道、FIFO、消息队列、信号量、共享内存。 

    1.管道,还有命名管道和非命名管道(即匿名管道)之分,非命名管道(即匿名管道)只能用于父子进程通讯,命名管道可用于非父子进程,命名管道就是FIFO,管道是先进先出的通讯方式    

    2.消息队列,是用于两个进程之间的通讯,首先在一个进程中创建一个消息队列,然后再往消息队列中写数据,而另一个进程则从那个消息队列中取数据。需要注意的是,消息队列是用创建文件的方式建立的,如果一个进程向某个消息队列中写入了数据之后,另一个进程并没有取出数据,即使向消息队列中写数据的进程已经结束,保存在消息队列中的数据并没有消失,也就是说下次再从这个消息队列读数据的时候,就是上次的数据!!!!    

    3.信号量,它与WINDOWS下的信号量是一样的,所以就不用多说了    

    4.共享内存,类似于WINDOWS下的DLL中的共享变量,但LINUX下的共享内存区不需要像DLL这样的东西,只要首先创建一个共享内存区,其它进程按照一定的步骤就能访问到这个共享内存区中的数据,当然可读可写      

    以上几种方式的比较:    

    1.管道:速度慢,容量有限,只有父子进程能通讯    

    2.FIFO:任何进程间都能通讯,但速度慢    

    3.消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题    

    4.信号量:不能传递复杂消息,只能用来同步    

    5.共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不过没这个必要,线程间本来就已经共享了同一进程内的一块内存

       本质上,信号量是一个计数器,它用来记录对某个资源(如共享内存)的存取状况。一般说来,为了获得共享资源,进程需要执行下列操作:

       (1)测试控制该资源的信号量;
       (2)若此信号量的值为正,则允许进行使用该资源,进程将进号量减1;
       (3)若此信号量为0,则该资源目前不可用,进程进入睡眠状态,直至信号量值大于0,进程被唤醒,转入步骤(1);
       (4)当进程不再使用一个信号量控制的资源时,信号量值加1,如果此时有进程正在睡眠等待此信号量,则唤醒此进程。
        套接字通信并不为Linux所专有,在所有提供了TCP/IP协议栈的操作系统中几乎都提供了socket,而所有这样操作系统,对套接字的编程方法几乎是完全一样的

    三、进程/线程同步机制与进程间通信机制比较

    很明显2者有类似,但是差别很大

    同步主要是临界区、互斥、信号量、事件

    进程间通信是管道、内存共享、消息队列、信号量、socket

    共通之处是,信号量和消息(事件)

    小结:

    1. 进程互斥、同步与通信的关系:进程竞争资源时要实施互斥,互斥是一种特殊的同步,实质上需要解决好进程同步问题,进程同步是一种进程通信,由此看来,进程互斥、同步都可以看做进程的通信;
    2. 信号量是进程同步与互斥的常用方法,也可以作为低级的进程通信方法,用于传递控制信号;

    3. 管道与管程是不同的,管程是进程同步的方式,而管道则是进程通信的方式;

     


    展开全文
  • 进程的同步与通信,进程与线程同步的区别,进程与线程通信的区别 进程同步与互斥的区别? 进程的同步方式有哪些? 进程的通信方式有哪些? 进程同步与通信的区别是什么? 线程的同步/通信与进程的同步/通信有...

    进程的同步与通信,进程与线程同步的区别,进程与线程通信的区别

     

    1. 进程同步与互斥的区别?
    2. 进程的同步方式有哪些?
    3. 进程的通信方式有哪些?
    4. 进程同步与通信的区别是什么?
    5. 线程的同步/通信与进程的同步/通信有区别吗?

    在好多教材上(包括国内与国外的)也没有明确这些概念,现在对每个问题还没有准确的答案,下面将自己的理解记下来,以后再补充。

    参考资料:

    《操作系统教程》 孙钟秀主编 费翔林  骆斌  谢立参编 高等教育出版社

    《计算机操作系统》 何炎祥 李飞 李宁 编著 清华大学出版社(进程管理部分与《操作系统教程》中的类似)

    进程互斥、同步的概念

    进程互斥、同步的概念是并发进程下存在的概念,有了并发进程,就产生了资源的竞争与协作,从而就要通过进程的互斥、同步、通信来解决资源的竞争与协作问题。

    下面是根据《操作系统教程》3.1.4 中的介绍,整理的进程互斥、同步的概念。

    在多道程序设计系统中,同一时刻可能有许多进程,这些进程之间存在两种基本关系:竞争关系和协作关系。

    进程的互斥、同步、通信都是基于这两种基本关系而存在的,为了解决进程间竞争关系(间接制约关系)而引入进程互斥;为了解决进程间松散的协作关系( 直接制约关系)而引入进程同步;为了解决进程间紧密的协作关系而引入进程通信。

    第一种是竞争关系 

    系统中的多个进程之间彼此无关,它们并不知道其他进程的存在,并且也不受其他进程执行的影响。例如,批处理系统中建立的多个用户进程, 分时系统中建立的多个终端进程。由于这些进程共用了一套计算机系统资源,因而, 必然要出现多个进程竞争资源的问题。当多个进程竞争共享硬设备、存储器、处理器 和文件等资源时,操作系统必须协调好进程对资源的争用。

    资源竞争出现了两个控制问题:一个是死锁 (deadlock )问题,一组进程如果都获得了部分资源,还想要得到其他进程所占有的资源,最终所有的进程将陷入死锁。另一个是饥饿(starvation )问题,这是指这样一种情况:一个进程由于其他进程总是优先于它而被无限期拖延。

    操作系统需要保证诸进程能互斥地访问临界资源,既要解决饥饿问题,又要解决死锁问题。 
        进程的互斥(mutual exclusion )是解决进程间竞争关系( 间接制约关系) 的手段。 进程互斥指若干个进程要使用同一共享资源时,任何时刻最多允许一个进程去使用,其他要使用该资源的进程必须等待,直到占有资源的进程释放该资源。

    第二种是协作关系          

    某些进程为完成同一任务需要分工协作,由于合作的每一个进程都是独立地以不可预知的速度推进,这就需要相互协作的进程在某些协调点上协 调各自的工作。当合作进程中的一个到达协调点后,在尚未得到其伙伴进程发来的消息或信号之前应阻塞自己,直到其他合作进程发来协调信号或消息后方被唤醒并继续执行。这种协作进程之间相互等待对方消息或信号的协调关系称为进程同步。

    进程间的协作可以是双方不知道对方名字的间接协作,例如,通过共享访问一个缓冲区进行松散式协作;也可以是双方知道对方名字,直接通过通信机制进行紧密协作。允许进程协同工作有利于共享信息、有利于加快计算速度、有利于实现模块化程序设计。

    进程的同步(Synchronization)是解决进程间协作关系( 直接制约关系) 的手段。进程同步指两个以上进程基于某个条件来协调它们的活动。一个进程的执行依赖于另一
    个协作进程的消息或信号,当一个进程没有得到来自于另一个进程的消息或信号时则需等待,直到消息或信号到达才被唤醒。

    不难看出,进程互斥关系是一种特殊的进程同步关系,即逐次使用互斥共享资源,也是对进程使用资源次序上的一种协调。

    进程通信的概念

    下面是根据《操作系统教程》3.5 中的介绍,整理的进程通信的概念。

    并发进程之间的交互必须满足两个基本要求:同步和通信。

    进程竞争资源时要实施互斥,互斥是一种特殊的同步,实质上需要解决好进程同步问题,进程同步是一种进程通信,通过修改信号量,进程之间可建立起联系,相互协调运行和协同工作。但是信号量与PV操作只能传递信号,没有传递数据的能力。有些情况下进程之间交换的信息量虽很少,例如,仅仅交换某个状态信息,但很多情况下进程之间需要交换大批数据,例如,传送一批信息或整个文件,这可以通过一种新的通信机制来完成,进程之间互相交换信息的工作称之为进程通信IPC (InterProcess Communication)(主要是指大量数据的交换)。进程间通信的方式很多,包括: 

    1 mmap(文件映射)

    2 信号

    3 管道

    4 共享内存

    5 消息队列(重要)

    6 信号量集(与signal无关)

    7 网络(套接字)

    进程同步的方法

    前面提到,进程互斥关系是一种特殊的进程同步关系,下面给出常见的进程同步的方法,实际上也可用于进程的互斥(个人理解)。

     Linux 下常见的进程同步方法有:

     1、信号量

     2、管程

     3、 互斥量(基于共享内存的快速用户态 )

     4、文件锁(通过 fcntl 设定,针对文件)

     针对线程(pthread)的还有 pthread_mutex 和 pthread_cond(条件变量)。

    线程的同步方法:

    1、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。 
    2、互斥量:为协调共同对一个共享资源的单独访问而设计的。 
    3、信号量:为控制一个具有有限数量用户资源而设计。 
    4、事 件:用来通知线程有一些事件已发生,从而启动后继任务的开始。

    线程间的通信方式

    1.锁机制:包括互斥锁、条件变量、读写锁

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

    b.读写锁允许多个线程同时读共享数据,而对写操作是互斥的。

    c.条件变量可以以原子的方式阻塞进程,直到某个特定条件为真为止。对条件的测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用。

    2. 信号量机制(Semaphore):包括无名线程信号量和命名线程信号量

    3. 信号机制(Signal):类似进程间的信号处理线程间的通信目的主要是用于线程同步,所以线程没有像进程通信中的用于数据交换的通信机制。

    进程同步的方法

    前面提到,进程互斥关系是一种特殊的进程同步关系,下面给出常见的进程同步的方法,实际上也可用于进程的互斥(个人理解)。

    在何炎祥的《计算机操作系统》 3.2 节,将进程同步的机制与解决进程互斥方法看做是一样的,的明确指出互斥的软件解决方法为Dekker算法与Peterson算法,互斥的硬件解决方法为中断方法、以及使用机器指令的方法,后面又给出了信号量、管程、消息传递三种方法。

    实际应用中,不同的系统有不同的进程同步方法,CSDN帖子http://bbs.csdn.net/topics/80156687中有一些讨论,Linux 与Windows的主要同步、通信机制如下:

    Linux 下:

    Linux 下常见的进程同步方法有:SysVIPC 的 sem(信号量)、file locking / record locking(通过 fcntl 设定的文件锁、记录锁)、futex(基于共享内存的快速用户态互斥锁)。针对线程(pthread)的还有 pthread_mutex 和 pthread_cond(条件变量)。
     
    Linux 下常见的进程通信的方法有 :pipe(管道),FIFO(命名管道),socket(套接字),SysVIPC 的 shm(共享内存)、msg queue(消息队列),mmap(文件映射)。以前还有 STREAM,不过现在比较少见了(好像)。

    Windows下:
    在Windwos中,进程同步主要有以下几种:互斥量、信号量、事件、可等计时器等几种技术。

    在Windows下,进程通信主要有以下几种:内存映射、管道、消息等,但是内存映射是最基础的,因为,其他的进程通信手段在内部都是考内存映射来完成的。

    线程的同步/通信与进程的同步/通信有区别吗?

    对于该问题,教材上没有明确的回答,教材上给出的一般是进程而非线程的同步、通信方式。但网络上很多说法将两者混为一谈。根据教材,以及网上的说法,个人的理解为:

    同步机制:

    信号量、管程、互斥是进程的同步机制,而信号量、互斥也可用于线程的同步,但管程只在进程同步中被用到;

    线程的同步除了信号量、互斥外,还有临界区、事件,没有看到教材上将这两种方式作为进程的同步方式;

    通信机制:

    管道、FIFO、消息队列、信号量、共享内存是进程的同步机制,教材上没有线程的通信机制这样的说法,但可以肯定这几种方法是进程的通信方式,且其中的信号量既可用于进程的同步,又可用于进程的通信,在网络上还有说可以用于线程同步的。

    管道与管程是不同的,管程是进程同步的方式,而管道则是进程通信的方式。

    进程的同步/通信

    下面是常见的线程之间的同步方式的详细介绍。

    (注:下面转自网络,下面的同步、通信方式对于进程与线程分的不是很清楚,关于进程还是线程的解释见上面——线程的同步/通信与进程的同步/通信有区别吗?)

    一、线程同步机制。

    临界区、互斥量、事件、信号量四种方式
    临界区(Critical Section)、互斥量(Mutex)、信号量(Semaphore)、事件(Event)的区别
    1、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。

    在任意时刻只允许一个线程对共享资源进行访问,如果有多个线程试图访问公共资源,那么在有一个线程进入后,其他试图访问公共资源的线程将被挂起,并一直等到进入临界区的线程离开,临界区在被释放后,其他线程才可以抢占。
    2、互斥量:采用互斥对象机制。

    只有拥有互斥对象的线程才有访问公共资源的权限,因为互斥对象只有一个,所以能保证公共资源不会同时被多个线程访问。互斥不仅能实现同一应用程序的公共资源安全共享,还能实现不同应用程序的公共资源安全共享 .互斥量比临界区复杂。因为使用互斥不仅仅能够在同一应用程序不同线程中实现资源的安全共享,而且可以在不同应用程序的线程之间实现对资源的安全共享。
    3、信号量:它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目 .

    信号量对象对线程的同步方式与前面几种方法不同,信号允许多个线程同时使用共享资源,这与操作系统中的PV操作相同。它指出了同时访问共享资源的线程最大数目。它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。

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

    总结:
      1. 互斥量与临界区的作用非常相似,但互斥量是可以命名的,也就是说它可以跨越进程使用。所以创建互斥量需要的资源更多,所以如果只为了在进程内部是用的话使用临界区会带来速度上的优势并能够减少资源占用量。因为互斥量是跨进程的互斥量一旦被创建,就可以通过名字打开它。
      2. 互斥量(Mutex),信号灯(Semaphore),事件(Event)都可以被跨越进程使用来进行同步数据操作,而其他的对象与数据同步操作无关,但对于进程和线程来讲,如果进程和线程在运行状态则为无信号状态,在退出后为有信号状态。所以可以使用WaitForSingleObject来等待进程和线程退出。
      3. 通过互斥量可以指定资源被独占的方式使用,但如果有下面一种情况通过互斥量就无法处理,比如现在一位用户购买了一份三个并发访问许可的数据库系统,可以根据用户购买的访问许可数量来决定有多少个线程/进程能同时进行数据库操作,这时候如果利用互斥量就没有办法完成这个要求,信号灯对象可以说是一种资源计数器。

    二、进程间通信方式

    由于比较容易混淆,我们把进程间通信方法也列在这里做比较。

    进程通信也就是所谓的IPC问题,主要是指进程间交换数据的方式。进程通信包括高级通信与低级通信,其中进程同步与互斥属于低级通信,主要用于插U农地控制信号;高级通信包括三种:共享存储系统(有的地方称作共享内存区)、消息传递系统(有的地方称作消息队列)、管道。

    信号量是进程同步与互斥的常用方法,也可以作为低级的进程通信方法,用于传递控制信号。

    简而言之,进程间通信方式主要包括管道、FIFO、消息队列、信号量、共享内存。 

    1.管道,还有命名管道和非命名管道(即匿名管道)之分,非命名管道(即匿名管道)只能用于父子进程通讯,命名管道可用于非父子进程,命名管道就是FIFO,管道是先进先出的通讯方式    

    2.消息队列,是用于两个进程之间的通讯,首先在一个进程中创建一个消息队列,然后再往消息队列中写数据,而另一个进程则从那个消息队列中取数据。需要注意的是,消息队列是用创建文件的方式建立的,如果一个进程向某个消息队列中写入了数据之后,另一个进程并没有取出数据,即使向消息队列中写数据的进程已经结束,保存在消息队列中的数据并没有消失,也就是说下次再从这个消息队列读数据的时候,就是上次的数据!!!!    

    3.信号量,它与WINDOWS下的信号量是一样的,所以就不用多说了    

    4.共享内存,类似于WINDOWS下的DLL中的共享变量,但LINUX下的共享内存区不需要像DLL这样的东西,只要首先创建一个共享内存区,其它进程按照一定的步骤就能访问到这个共享内存区中的数据,当然可读可写      

    以上几种方式的比较:    

    1.管道:速度慢,容量有限,只有父子进程能通讯    

    2.FIFO:任何进程间都能通讯,但速度慢    

    3.消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题    

    4.信号量:不能传递复杂消息,只能用来同步    

    5.共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不过没这个必要,线程间本来就已经共享了同一进程内的一块内存

       本质上,信号量是一个计数器,它用来记录对某个资源(如共享内存)的存取状况。一般说来,为了获得共享资源,进程需要执行下列操作:

       (1)测试控制该资源的信号量;

       (2)若此信号量的值为正,则允许进行使用该资源,进程将进号量减1;

       (3)若此信号量为0,则该资源目前不可用,进程进入睡眠状态,直至信号量值大于0,进程被唤醒,转入步骤(1);

       (4)当进程不再使用一个信号量控制的资源时,信号量值加1,如果此时有进程正在睡眠等待此信号量,则唤醒此进程。
        套接字通信并不为Linux所专有,在所有提供了TCP/IP协议栈的操作系统中几乎都提供了socket,而所有这样操作系统,对套接字的编程方法几乎是完全一样的

    三、进程/线程同步机制与进程间通信机制比较

    很明显2者有类似,但是差别很大

    同步主要是临界区、互斥、信号量、事件

    进程间通信是管道、内存共享、消息队列、信号量、socket

    共通之处是,信号量和消息(事件)

    小结:

    1. 进程互斥、同步与通信的关系:进程竞争资源时要实施互斥,互斥是一种特殊的同步,实质上需要解决好进程同步问题,进程同步是一种进程通信,由此看来,进程互斥、同步都可以看做进程的通信;
    2. 信号量是进程同步与互斥的常用方法,也可以作为低级的进程通信方法,用于传递控制信号;

    3. 管道与管程是不同的,管程是进程同步的方式,而管道则是进程通信的方式;

    进程和线程的区别与联系

    1. 从概念出发
    进程是程序运行的活动实体,操作系统会为一个进程分配TCP(进程控制块),虚拟地址空间,页表等一些资源。 
    线程是轻量级进程,是程序运行的某一片段,是进程内部的一部分,操作系统只会给它分配一点够程序运行的资源,所有线程共享进程的地址空间。

    2. 资源分配与调度
    所以进程是资源分配的最小单位,线程是调度的最小单位。

    3.资源占有角度
    操作系统会为一个进程分配一堆资源,所有的进程之间是独立的,是互不影响的。 
    而所有线程共享进程的虚拟地址空间,只拥有一小部分资源,比如自己的线程ID,私有栈空间,自己的上下文数据等。 
    就是因为线程共享资源,所以一个线程的异常退出会影响整个进程异常退出,并且要注意线程间的同步与互斥问题。

    4. 调度与切换
    (1)因为进程携带一大堆的资源,所以创建和撤销一个进程的代价要比创建和撤销一个线程大的多。 
    (2)因为进程携带一堆资源,所以进行进程之间的切换或调度时,操作系统要做的工作比线程之间的切换或调度多得多。

    5. 通信
    对于进程间通信,最主要就是让两个不相干的进程之间看到同一份资源,但是对于两个进程而言,通信要比线程难得多,两个线程之间的通信是很容易进行的。

    6. 并行
    不仅进程间可以并发执行,线程之间也可以并发执行。但是由于进程的创建、撤消和切换,系统的开销比较大,所以创建的进程数目不能太多,而线程的划分尺度比进程小,所以并发性比进程高,效率和吞吐量都比较高。 
    线程在执行程序的过程中,每个线程有自己的程序入口,函数栈帧,函数出口等。

    7. 创建线程和进程
    在Linux下,创建一个子进程可以用fork和vfork函数,在子进程运行完毕后,必须由父进程对子进程进行回收(wait,waitpid,发送信号),否则子进程会成为僵尸进程,会造成资源泄漏。 
    创建一个新线程可以用pthread_create函数,在新线程运行完成后,也必须回收,否则会造成资源泄漏。如果不想回收,则可以利用detach函数对线程进行分离。

    【补充:线程的优缺点】 
    优点 
    (1)线程是轻量级进程,携带的资源很少,创建一个线程的代价较小。 
    (2)与进程间的切换相比,线程间的切换操作系统要做的工作较小。 
    (3)线程占用的资源很少。 
    (4)线程可以充分利用多处理器数量,并发性高。 
    (5)在等待慢速IO的同时,可以做计算型任务。 
    (6)对于计算密集型任务和IO密集型任务,线程的效率都比较高。 
    缺点 
    (1)性能缺失 
    假设在计算密集型任务中,创建了很多的线程,但是线程的数量比处理器的数量多,那么会造成多余线程在等待,造成性能缺失。 
    (2)安全性降低 
    容易引发线程安全等问题,需要使用多线程的同步与互斥机制。 
    (3)编程难度提高 
    编写与调试一个多线程程序比单线程困难的多。
     

    展开全文
  • 进程的同步(Synchronization)是解决进程间协作关系( 直接制约关系) 的手段。 进程同步指两个以上进程基于某个条件来协调它们的活动。一个进程的执行依赖于另一个协作进程的消息或信号,当一个进程没有得到来自于另...

    进程的互斥(mutual exclusion )是解决进程间竞争关系( 间接制约关系) 的手段。

    进程互斥指若干个进程要使用同一共享资源时,任何时刻最多允许一个进程去使用,其他要使用该资源的进程必须等待,直到占有资源的进程释放该资源。

    进程的同步(Synchronization)是解决进程间协作关系( 直接制约关系) 的手段。

    进程同步指两个以上进程基于某个条件来协调它们的活动。一个进程的执行依赖于另一个协作进程的消息或信号,当一个进程没有得到来自于另一个进程的消息或信号时则需等待,直到消息或信号到达才被唤醒。

    不难看出,进程互斥关系是一种特殊的进程同步关系,即逐次使用互斥共享资源,也是对进程使用资源次序上的一种协调。

    进程的同步、互斥、通信的区别,进程与线程同步的区别
    Linux IPC总结(全)

    展开全文
  • 进程的同步与互斥区分

    千次阅读 2016-02-02 16:56:08
    进程的同步与互斥区分

    进程同步:进程间的直接制约关系,是为完成某种任务而建立的两个或多个线程,这个线程需要在某些位置上协调他们的工作次序而等待、传递信息所产生的制约关系。进程间的直接制约关系来源于他们之间的合作。

    进程互斥:进城之间的间接制约关系。当一个进程进入临界区使用临界资源时,另一个进程必须等待。只有当使用临界资源的进程退出临界区后,这个进程才会解除阻塞状态。

    其实同步与互斥在本质上而言是差不多的,都是在使用资源使约束资源,防止其他进程共同使用,以免造成错误使用错误。同步是有序访问资源,是更复杂的互斥;互斥是单一进程访问资源,具有唯一性与排它性,是特殊的同步。

    而有些比较特别的模式,如生产者消费者模式,就是两种情况存在,既需要同步又需要互斥,从这可以看出其实同步与互斥的使用经常混合在一起。

    展开全文
  • 把并发进程的同步和互斥问题一般化,可以得到一个抽象的一般模型,即生产者-消费者问题。 在计算机系统中,每个进程都申请使用和释放各种不同类型的资源,这些资源既可以是像外设、内存及缓冲区等硬件资源,也可以...
  • 进程的同步和PV操作 同步和互斥的概念 互斥关系:多个进程由于共享了独占资源,必须协调各进程对资源的存取顺序:确保没有两个或两个以上的进程同时进行存取操作。 同步关系:若干合作进程为了完成一个共同任务...
  • 2.3.1 进程的同步与互斥

    千次阅读 2020-03-18 13:36:54
    文章目录0.思维导图1.进程同步2.进程互斥 0.思维导图 ...进程同步是为了解决进程的异步问题。 一个简单的例子来理解这个概念。 例如,让系统计算1 + 2x3,假设系统产生两个进程: 一个是加法进程,一个是...
  • 信号量解决进程的同步和互斥

    千次阅读 2015-08-03 10:46:44
    用信号量解决进程的同步与互斥探讨【持续更新】  现代操作系统采用多道程序设计机制,多个进程可以并发执行,CPU在进程之间来回切换,共享某些资源,提高了资源的利用率,但这也使得处理并发执行的多个进程之间的...
  • linux 下多进程的同步

    千次阅读 2011-10-18 14:37:42
    linux 多进程的同步:linux多进程我实现同步操作,操作单个信号量已经不能实现,对多进程的通信可以采取信号集的方式,一个信号集包含了多个信号量。 首先通过semget()创建信号量。例如:semid = semget(SEMKEY,2...
  • 经典进程的同步问题

    千次阅读 2017-04-05 15:43:17
    操作系统进程同步问题一些经典例子学习。
  • 本文分别介绍三个经典进程的同步问题,即“生产者-消费者问题”、“哲学家进餐问题”以及“读者-写者问题”。
  • 进程的同步与互斥概念原理

    千次阅读 2018-07-17 11:56:56
    进程同步是一个操作系统级别概念,是在多道程序环境下,存在着不同制约关系,为了协调这种互相制约关系,实现资源共享和进程协作,从而避免进程之间冲突,引入了进程同步。 临界资源 在操作系统中,...
  • 用P,V操作实现爸爸、妈妈、儿子、女儿进程的同步控制。 补充:设有两个篮子,分别有若干个苹果或橘子,爸爸和妈妈将每次从水果篮子中拿出一个水果放入水果盘中,儿子女儿则挑选各自喜欢的水果。
  • 进程的同步和异步

    2016-05-23 17:21:05
    Java中交互方式分为同步和异步两种: 同步交互:指发送一个请求,需要等待返回,然后才能够发送下一个请求,有个等待过程;...同步可以避免进程之间死锁 ,读脏数据可能性发生,一般在项目中如
  • 在SV中,可以使用event来实现进程之间的同步,在UVM中也与专门的类来实现进程之间的同步: uvm_event#(typeT=uvm_object)。 uvm_event相比于event最大的优势是可以实现不同组件之间的同步。比如组件A,B要实现同步...
  • 进程的同步与异步

    千次阅读 2013-11-05 22:04:53
    进程同步用来实现程序并发执行时候可再现性。 一.进程同步及异步概念 1.进程同步:就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。也就是必须一件一件事做,等前一件做完了才能做下一件事.就...
  • 进程的同步与互斥

    2016-03-10 18:50:18
    如果对并发进程的调度不当,则可能会出现运行结果与切换时间有关的情况,令结果不可再现,影响系统的效率和正确性,严重时还会使系统直接崩溃。 多进程的系统中避免不了进程间的相互关系。进程间的关系主要有两种...
  • 在说到进程的同步的问题上,毫无疑问,生产者与消费者这个经典问题是不可避免的。   生产者生产的前提是:生产者生产出来的产品容器还能够装下,否则等待消费者消费; 消费者消费的前提是:容器中有产品能够让...
  • 桌上有一空盘,最多允许存放一颗水果。...试用wait,signal操作实现爸爸儿子,女儿三个并发进程的同步,(提示:设置一个信号量表示可否向盘中放水果,一个信号量表示可否去橘子,一个信号量表示可否取苹果。)
  • //两个或更多进程在协作时需保持互斥 //进程的并发执行特征 //P,V操作 #include <sys.h>semaphore mutex=1;int x; void process_one() { int y,z; P(mutex); //wait(mutex); x=1; y=0; if(x>=1) y=y+1; z=y;
  • 进程同步与互斥: (一)临界资源: (1)定义: 一次只允许一个进程访问资源为临界资源。 临界区:访问临界资源那段区域为临界区。 (2)临界资源访问: 将临界资源访问分为四个部分: 进入区-》...
  • 常用进程的同步机制

    2012-10-14 21:28:31
    一、原子操作 所谓原子操作是指不会被线程调度机制打断操作。...原子操作不需要同步机制。 P.S:volatile修饰long和double型赋值和返回是原子操作 二、信号量机制
  • 问题描述: 有一群生产者进程在生产产品,...尽管所有生产者进程都是以异步方式运行,但它们之间必须保持同步,既不允许消费者进程到一个空缓冲去取产品,也不允许生产者进程向一个已装满产品且尚未被取走缓...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 29,959
精华内容 11,983
关键字:

进程的同步