• 游戏大厅 从基础开始(6)绕回来细说聊天室(中)之女仆编年史1


    上一篇我们大致的了解了几种聊天室的行为模式

    最简单明了的推模式 几乎不需要任何多余的语言来描述它的实现

    这一篇我们看看如何实现拉模式更有效。

      

      

      

       

       

    本图清晰的表现了""模式聊天室的行为。

    • 并发多用户向数据池写数据
    • 并发多用户从数据池读书据
    • 数据最好以时间为顺序储存在集合中
    • 某时间向后的枚举查找将是最大的消耗。

      

      

    聊天室进化 -女仆编年史

    神秘的原始社会

    仍然参考我们神奇朴素的Asp3聊天室

    53     Application.lock
    54         Application("show5")=Application("show4") '
    一条新信息驾到 第五条信息被淘汰
    55         Application("show4")=Application("show3")
    56         Application("show3")=Application("show2")
    57         Application("show2")=Application("show")
    58         Application("show")=NewMessage     '
    其他所有的信息向前移动一次给新的信息让个位置。
    59     Application.UnLock
    60     Response.Write Application("show5")
    61     Response.Write Application("show4") '
    由于是postback 模式 必须输出历史n行数据
    62     Response.Write Application("show3")
    63     Response.Write Application("show2")
    64     Response.Write Application("show")

    从线程安全角度来说 本来 response.write应该也在 application .lock 块中  或者分开两个lock块.  但是这里由于response.write 在非cache模式下可能带来的时间延迟 作者煞费苦心的把他们从安全锁中移动出来.在实际运行中 很可能出现丢话或者重复发言的状况

    application究竟 被人做了些什么? 没有边界  没有抽象包装的这个实现就好像原始共产主义 谁是谁的谁啊这都是!

      

     

    私有制出现,奴隶社会 LOCK~ 这个女奴是我的~

    翻译成c# 我们可以看到一个比较容易理解的逻辑 当然这个代码稍微有所修改 两个锁很明确 很完美的把数据和线程排起了队伍

      

    Code Snippet

    1.        class Channel
    2.         {
    3.             Queue<string> MessageQ = new Queue<string>();
    4.  
    5.             public void Say(string message) //写信息
    6.             {
    7.                 lock (MessageQ)
    8.                 {
    9.                     MessageQ.Enqueue(message);
    10.                     while (MessageQ.Count > 5)  // 删多余
    11.                     {
    12.                         MessageQ.Dequeue();
    13.                     }
    14.  
    15.                 }
    16.             }
    17.  
    18.             public string[] Listen() //\u-28781 ?出所有
    19.             {
    20.                 lock (MessageQ)
    21.                 {
    22.                     return MessageQ.ToArray();
    23.  
    24.                 }
    25.  
    26.             }
    27.  
    28.          }

      

    在aspx可能这样调用

    Code Snippet

    1.             Channel cr = session["Chat"];
    2.             cr.Say(Request["text"]);
    3.  
    4.             foreach (var s in cr.Listen())
    5.             {
    6.                 Response.write("<p>");
    7.                 Response.write(s);
    8.                 Response.write("</p>");
    9.             }

    看起来圆满完成任务 但是里面充满了暧昧    

     

    类似事务 或者访问非托管资源 在访问线程临界资源的时候有个原则

    你尽可能的晚锁 尽可能的早释放,

    看看刚刚做了些什么

    Oh My God

    我们可怜的Channel阿  他被全程锁定。好像一个被老爷少爷轮流调教的女奴啊,真让我等正人君子心潮澎湃~~  啊不对  是于心不忍。

    由于每个调教者在调教前声明:这个女奴是“我雷瓦Mono”我的东西! 所以在调教者声明 这个女仆“亚没漏”不要了之前 谁也不许碰!

    LOCK LOCK~

    这才是两个主人并发访问  就已经造成了这么多等待,如果是100主人个并发调教,那得是多么壮观的队伍!

    我们的服务程序如果按照这个效率编写 恐怕cpu占用25%的时候就会崩溃---线程队列的极限是多少?  按照Jeffery Richard 的话说 你提出这个问题的时候 就已经Very Very Wrong鸟。

    换句话说,不要挑战爷们的耐性,后果很严重

    社会要进步 人民要革命  封建时代来临

    我们不能满足这样的性能

    老爷调教女奴的时候少爷不观摩 这我们理解,(写的时候加lock防止别的线程读)

    少爷和女仆喝茶的时候  老爷不能乱入开始餐厅调教,这我们也接受 (读的时候加lock防止别的线程写)

    但是少爷们找女奴喝茶,没有道理不可以一起开茶话会吧!

    从某种意义上,只要集合元素不变化的话, Queue对象是支持安全的并发读的,为什么几个线程都在读取的状况下,我们还要继续上锁彼此排斥对方呢? 我们只是纯粹对女仆有爱,没什么不可以光明正大的吧!

    把锁从完全锁变成读写锁,能够有效的减少很多不需要的等待。——  我们可以把喝茶的队伍缩短!

    Code Snippet
    1.        class ChannelReadWriteLock
    2.         {
    3.             Queue<string> MessageQ = new Queue<string>();
    4.             System.Threading.ReaderWriterLockSlim _lock = new System.Threading.ReaderWriterLockSlim();
    5.             public void Say(string message) //写信息
    6.             {
    7.                 _lock.EnterWriteLock();
    8.                 
    9.                     MessageQ.Enqueue(message);
    10.                     while (MessageQ.Count > 5)  // 删多余
    11.                     {
    12.                         MessageQ.Dequeue();
    13.                     }
    14.                 _lock.ExitWriteLock ();
    15.             }
    16.             public string[] Listen() //   \u-29701 ?所有
    17.             {
    18.                  _lock.EnterReadLock ();
    19.                   var ary= MessageQ.ToArray();
    20.                 _lock.ExitReadLock();
    21.                 return ary;
    22.             }
    23.         \

    这是女仆界的胜利 她不再是一个人(的人) 而是可以和人socal的普通人了  虽然还在封建家长制的阴影下,仍然是被剥削被蹂躏的底层民众,但是她已经具有了比以前更大的自由!

    先写到这里看看和谐底限 敬请期待   女仆编年史2

  • 相关阅读:
    (OK) error: code model kernel does not support PIC mode
    compile android for x86_64
    内核开发的前途在什么地方,发展方向有哪些?
    SOA 与 MSA(微服务架构)
    [Android] adb命令如何获取android手机屏幕分辨率
    (2) 在 Build 系统中添加新的内容
    (1) 理解 Android Build 系统
    (OK) [solved] error
    Error while building CM 13 (KERNEL_OBJ/usr, needed by libtinyalsa_intermediates/mixer.o)
    (OK) http://www.android-x86.org
  • 原文地址:https://www.cnblogs.com/waynebaby/p/1551761.html
Copyright © 2020-2023  润新知