zoukankan      html  css  js  c++  java
  • 线程同步

    线程同步的方法主要有以下五种:

    1、临界区:通过临界区实现多个线程对同一公共资源或一段代码的串行访问,速度快,适合控制数据的访问。

    2、互斥量:通过协调线程共同对一个共享资源的单独访问而设计。

    3、信号量:可以控制有限用户对同一资源的的访问而设计;

    4、事件:通过通知线程的有一些事件已经发生,从而可以启动后续的任务执行。

    5、互锁函数:通过互锁函数为同步多线程同时访问共享变量提供了一个简单的机制。

     

    1、临界区(Critical Section):

        保证某一时刻只有一个线程访问某一资源的简便方法。任意时刻只允许一个线程对资源的访问。如果同一时刻由多个线程试图访问临界区,则其中一个线程进入临界区后,其它线程将会被挂起等待,并一直持续到该线程退出临界区。当临界区被释放后,其它线程可以抢占,并以此达到原子方式操作共享资源的目的。

        临界区的两个原语:EnterCriticalSection() 进入临界区;LeaveCriticalSection()退出临界区。

     

    2、互斥量(Mutex)

        互斥量跟临界区很相似,只有拥有互斥对象的线程才具有访问资源的权限。由于互斥对象只有一个,因此就决定了同时只有一个线程拥有对资源的访问权限。当前占据资源的线程在任务处理完成后交付互斥对象,以便其它线程可以拥有该互斥对象实现对资源的控制访问。互斥量比临界区复杂,互斥量不仅可以实现同一应用程序的不同线程间的同步,而且可以实现不同程序间线程的对资源的安全共享。

        互斥量包含的几个操作原语:

        CreateMutex()创建互斥量

        OpenMutex()打开互斥量

        ReleaseMutex()释放互斥量

        WaitForMultipleObjects() 等待互斥对象

     

    3、信号量(Semaphores)

         信号量对线程同步的方法与前几种不同,信号量允许多个线程同时使用共享资源,这与操作系统中的PV操作相同。它指出了同时访问共享资源的最大线程数目。它允许多个线程在同一时刻访问同一资源,但是限制了同一时刻访问资源的最大线程数目。在用CreateSemaphore()创建信号量时,要同时指出允许访问的最大资源基数和当前可用资源计数。一般把当前可用资源计数作为最大资源计数,即每增加一个线程对资源的访问相应的资源计数就会减一,只要当前可用资源计数是大于0的,就可以发出信号量信号。但是当前可用资源减小到小于0时,则说明当前占用资源的线程数目已经达到最大,不允许线程的继续进入,此时信号量也无法发出。当线程处理完资源后,应该离开的同时通过ReleaseSemaphore()使资源计数加1。在任何时候当前可用资源数目不可用大于最大资源数目。

     

        PV操作是由荷兰科学家提出的。信号量S是一个整数,当S大于等于0时,代表可给并发进程使用的资源实体,但S小于零正在等待使用共享资源的数目。

     

       P操作申请资源:

       (1)S减1

        (2)若S减1后仍大于等于0,则进程继续;

       (3)若S减1后小于0,则进程被阻塞后放入该信号相应的队列中,然后转入进程调度;

      V操作释放资源:

      (1)S加1操作;

       (2)若S加1后大于0,则进程继续执行;

      (3)若S加1小于等于0,则从信号量的等待队列中唤醒一个等待进程,然后再返回原进程继续执行或转入进程调度。

       信号量包含的几个操作原语:

       CreateSemphore()创建一个信号量;

       OpenSemphore()打开一个信号量;

       ReleaseSemaphore()退出一个信号量;

       WaitForSingleObject()等待一个信号量

     

     4、事件(Event)

         事件对象也可以通过通知操作的方式保持线程同步,可以实现不同进程中的线程同步操作;

     

    5、互锁函数(InterLocked*)

         这种机制提供的是对于共享变量的访问情况,它只允许在同一时刻只有一个线程能够访问共享内存,所以对于进程、线程的同步都适用。主要额函数有InterlockedIncrement、InterlockedDecrement以及不常见的InterlockedExchangeAdd和InterlockedExchangePointer。

     

    总结:

       1、互斥量与临界区的作用非常相似。但互斥量是可以命名的,也就是说可以扩进程使用,所以创建互斥所需的资源更多,所以如果为了在进程内部使用的话,可以通过临界区来提高速度上的优势,并且可以减少资源的使用。互斥量是跨进程的,一旦被创建就可以通过名字打开。

     

      2、互斥量、信号量、互锁函数和事件都可以被跨越进程来进行进程同步数据操作,而其他的对象与数据同步操作无关,但对于进程和线程来讲,如果进程和线程在运行状态为无信号状态,在退出后为有信号状态。所以可以使用WaitForSingleObject来等待进程和线程退出。 

     

      3、通过互斥量可以指定资源独占的方式使用,但如果有下面一种情况,信号量就无法处理,比如一个用户购买了一份三个并发访问许可的数据可系统,可以根据用户购买的访问许可数量来决定由多少个线程/进程能同时进行数据库操作,这时候如果利用互斥量就没有办法完成请求,可以使用信号量。

    4、资源独占式(同一时刻对共享变量的访问只有一个线程):互锁函数,其他几个是代码段独占。

    5、允许进程同步的有:互斥量、信号量、互锁函数和事件

    PS:http://blog.sina.com.cn/s/blog_4a74be0a010006z4.html

  • 相关阅读:
    【编译原理】文法解析算法以及左递归消除算法
    【编译原理】 DFA词法分析和递归下降语法分析代码
    编译原理 第三章 词法分析(下)
    详解KMP算法
    编译原理 第三章 词法分析(上)
    ExtJs4.0入门错误
    致好友的一封信
    解析Xml四种方法
    Spring AOP实现原理
    Spring Ioc知识整理
  • 原文地址:https://www.cnblogs.com/arbboter/p/4225230.html
Copyright © 2011-2022 走看看