zoukankan      html  css  js  c++  java
  • 线程同步的情景之二

          情景一中,我主要介绍了用于解决资源争用时各种方式的区别,本篇文章我们将进一步介绍线程同步的第二种场景。

     情景二:数量有限,先到先得

     

      情景简介:与情景一类似,但是这次茅坑的数量不只一个。如果有需求的人数少于茅坑数量,那一切都很和谐。但是人数超过茅坑数量的时候该怎么办?多个人占用一个坑?

      解决办法:当所有茅坑都客满的时候,其他人必须乖乖等在外面,只有当有人从里面出来的时候,下一个人才能进去。

      问题抽象:当某一资源同一时刻允许一定数量的线程使用的时候,需要有个机制来阻塞多余的线程,直到资源再次变得可用。

      线程同步方案:Semaphore、SemaphoreSlim

      方案特性:限量供应;除所有者外,其他人无条件等待;先到先得(谁先进茅坑,谁先用,没有先后顺序

      各方案间的区别

      Semaphore 的中文名称叫信号量,在学操作系统的时候肯定都会讲到。而扯到信号量,最常拿来举的就是生产者与消费者的例子。与上一篇一样,我不会在这里重复介绍一些网上多的是的内容,大家如果有兴趣,可以自己去找度娘、必硬或谷哥。

      在继续阅读前,请确保你已经对用户模式构造、内核模式构造和混合模式构造有所了解,如果尚未了解,建议您先阅读情景一中相关章节。

    内核模式(kernal-mode)

      Semaphore 通过在构造函数中传入容器大小来限制一次性允许访问的线程数量。与情景一介绍中的 Mutex 一样属于内核模式,而且都拥有同一个祖宗:WaitHandle。但是与 Mutex 不一样的是,通过线程一获取的所有权,可以由线程二来释放。下面的写法是完全合法的。

        Task.Factory.StartNew(() =>
        {
            //类似于消费者
            semaphore.WaitOne();
            Thread.Sleep(5000);
        });
     
        Thread.Sleep(1000);
        Task.Factory.StartNew(() =>
        {
            //类似于生产者
            semaphore.Release();
        });

      优点:提供数量限制的能力,可以跨进程使用。

        //进程一
        Semaphore s = new Semaphore(1, 1, "myname", out creaded);
         
        //进程二
        Semaphore s = Semaphore.OpenExisting("myname");

      缺点:速度慢于用户模式、混合模式构造,稍快于 mutex。

    混合模式(hybrid-mode)

      SemaphoreSlim 是 .Net 4.0 时引进的一个新类型,使用方式上类似 Semaphore,是轻量级的 Semaphore。不允许跨进程使用。

      优点:提供数量限制的能力;速度快,优于 Semaphore。

      缺点:不能跨进程使用。

    总 结

      本篇文章介绍的方法主要用于解决资源有限(数量大于一)时线程同步的问题。如果资源唯一,那利用 Semaphore s = new Semaphore(1,1) 的效果与创建一个 Mutex 的效果实际是一致的。而此时的 Semaphore 会有一个新名称叫 Binary Semaphore (二元信号量)。

      那什么时候该使用 Semaphore, 什么时候使用 Mutex? 

      记住本系列强调的情景!如果用于资源争用,请使用 Mutex;如果用于限量使用请使用 Semaphore。

      本文来自《C# 基础回顾: 线程同步的情景之二

  • 相关阅读:
    【Java多线程】Fork/Join 源码分析(三十一)
    【Java多线程】Fork/Join 框架(三十)
    【Java】 Iterator(迭代器)
    【Java多线程】ScheduledThreadPoolExecutor实现原理(二十九)
    【Java多线程】ScheduledThreadPoolExecutor详解(二十八)
    【Java多线程】Executor框架 (二十七)
    【Python基础编程252 ● 包 ● 使用import 包名 as 别名 语句导包】
    【Python基础编程251 ● 包 ● 使用from 包名 import * 语句导包】
    【Python基础编程250 ● 包 ● 导包的方式】
    【Python基础编程249 ● 包 ● 包的基本概念、作用和命名规则】
  • 原文地址:https://www.cnblogs.com/stg609/p/4050483.html
Copyright © 2011-2022 走看看