程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> Visual Basic語言 >> VB.NET >> 游戲大廳從基礎開始(6)--繞回來細說聊天室(中)之女僕編年史1

游戲大廳從基礎開始(6)--繞回來細說聊天室(中)之女僕編年史1

編輯:VB.NET

上一篇我們大致的了解了幾種聊天室的行為模式

最簡單明了的推模式 幾乎不需要任何多余的 語言來描述它的實現

這一篇我們看看如何實現拉模式更有效。

本圖清晰的表現了 "拉"模式聊天室的行為。

並發多用戶向數據池寫數據

並發多用戶從數據池讀 書據

數據最好以時間為順序儲存在集合中

某時間向後的枚舉查找將是最大的消耗。

聊天室進化 -女僕編年史神秘的原始社會

仍然參考我們神奇樸素的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

class Channel
{
 Queue<string> MessageQ = new Queue<string>();

 public void Say(string message) //寫信息
 {
  lock (MessageQ)
  {
   MessageQ.Enqueue(message);
   while (MessageQ.Count > 5)  // 刪多余
   {
    MessageQ.Dequeue();
   }

  }
 }

 public string[] Listen() //u-28781 ?出所有
 {
  lock (MessageQ)
  {
   return MessageQ.ToArray();

  }

 }

}

在aspx可能這樣調用

Code Snippet

Channel cr = session ["Chat"];
cr.Say(Request["text"]);

foreach (var s in cr.Listen())
{
 Response.write("<p>");
 Response.write(s);
 Response.write("</p>");
}

看起來圓滿完成任務 但是裡面充滿了暧昧

類似事務 或者訪問非托管資源 在訪問線程臨 界資源的時候有個原則

你盡可能的晚鎖 盡可能的早釋放,

看看剛剛做了些什麼

大圖

Oh My God

我們可憐的Channel阿  他被全程鎖定。好像一個被老爺少爺輪流調教的女奴啊,真讓我等 正人君子心潮澎湃~~  啊不對  是於心不忍。

由於每個調教者在調教前聲明:這個女奴是 “我雷瓦Mono”我的東西! 所以在調教者聲明 這個女僕“亞沒漏”不要了之前 誰也不許碰!

LOCK LOCK~

這才是兩個主人並發訪問  就已經造成了這麼多等待,如果是 100主人個並發調教,那得是多麼壯觀的隊伍!

我們的服務程序如果按照這個效率編寫 恐怕cpu 占用25%的時候就會崩潰---線程隊列的極限是多少?  按照Jeffery Richard 的話說 你提出這個問題 的時候 就已經Very Very Wrong鳥。

換句話說,不要挑戰爺們的耐性,後果很嚴重

社會 要進步 人民要革命  封建時代來臨

我們不能滿足這樣的性能。

老爺調教女奴的時候少 爺不觀摩 這我們理解,(寫的時候加lock防止別的線程讀)

少爺和女僕喝茶的時候  老爺不能 亂入開始餐廳調教,這我們也接受 (讀的時候加lock防止別的線程寫)

但是少爺們找女奴喝茶 ,沒有道理不可以一起開茶話會吧!

從某種意義上,只要集合元素不變化的話, Queue對象是支持安全的並發讀的,為什麼幾個線程都在讀取的狀況下,我們還要繼續上鎖彼此排斥對方呢? 我們只是 純粹對女僕有愛,沒什麼不可以光明正大的吧!

把鎖從完全鎖變成讀寫鎖,能夠有效的減少很多 不需要的等待。——  我們可以把喝茶的隊伍縮短!

Code Snippet

class ChannelReadWriteLock
{

 Queue<string> MessageQ = new Queue<string>();
 System.Threading.ReaderWriterLockSlim _lock = new System.Threading.ReaderWriterLockSlim();
 public void Say(string message) //寫信息
 {
  _lock.EnterWriteLock();

  MessageQ.Enqueue(message);
  while (MessageQ.Count > 5)  // 刪多余
  {
   MessageQ.Dequeue();
  }

  _lock.ExitWriteLock ();
 }

 public string[] Listen() //   u-29701 ?所有
 {
  _lock.EnterReadLock ();

  var ary= MessageQ.ToArray();

  _lock.ExitReadLock();
  return ary;
 }

這是女僕界的勝利 她不再是一個人(的人) 而是可以和人socal的普通人了  雖然還在封建家長 制的陰影下,仍然是被剝削被蹂躏的底層民眾,但是她已經具有了比以前更大的自由!

大圖

先寫到這裡看看和諧 底限 敬請期待   女僕編年史2

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved