<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    kxbin
    成功留給有準備的人
    posts - 10,  comments - 35,  trackbacks - 0

    在多線程、多處理器甚至是分布式環境的編程時代,并發是一個不可回避的問題,很多程序員一碰到并發二字頭皮就發麻,也包括我。既然并發問題擺在面前一個到無法回避的坎,倒不如擁抱它,把它搞清楚,決心花一定的時間從操作系統底層原理到Java的基礎編程再到分布式環境等幾個方面深入探索并發問題。先就從原理開始吧。

    并發產生的原因

    雖然從直觀效果上,處理器是并行處理多項任務,但本質上一個處理器在某個時間點只能處理一個任務,屬于串行執行。在單處理器的情況下,并發問題源于多道程序設計系統的一個基本特性:進程的相對執行速度不可預測,它取決于其他進程的活動、操作系統處理中斷的方式以及操作系統的調度策略。在分布式環境下,并發產生的可能性就更大了,只要大家有依賴的共享資源,就有并發問題的出現,因為互相調用次序更加沒法控制。

    并發帶來的問題

    • 全局資源的共享充滿了危險。不同任務對同一個共享資源的讀寫順序非常關鍵
    • 操作系統很難對分配資源進行最優化管理。掛起的線程占有了其他活動線程需要的資源
    • 定位錯誤非常困難。這種問題來源和觸發的不確定性,導致定位問題非常困難
    • 限制分布式系統橫向擴展能力

    進程的交互

    進程的交互方式決定了并發問題產生的上下文,解決并發問題也需根據進程交互方式的不同而不同對待。一般進程交互分為以下三種:

    1)進程間相互獨立

    這種情況下雖然進程間沒有數據共享,所做事情也互不聯系,但它們存在競爭關系。計算機中有些臨界資源比如I/O設備、存儲器、CPU時間和時鐘等等都需要通過競爭得到,你占用的時候就得保證別人沒法占用,因此首先得解決這種互斥的需求。另外,要處理好這種臨界資源的調度策略,處理不當就有可能發生死鎖和饑餓

    2)進程間通過共享合作

    這種情況下進程間雖然執行的過程是相互獨立的,互不知道對方的執行情況,但互相之間有共享的數據。因此除了有以上互斥需求和死鎖饑餓的可能,另外還會有數據一致性的問題。當多個進程非原子性操作同一個數據時候,互相之間操作時序不當就有可能造成數據不一致

    3)進程間通過通信合作

    這種情況下進程間通過消息互相通信,知曉各自的執行情況,不共享任何資源,因此就可以避免互斥和數據不一致問題,但仍然存在死鎖和饑餓的問題

    并發問題的解決辦法

    操作系統解決并發問題一般通過互斥,為了提供互斥的支持,需要滿足以下需求:

    • 一次只允許一個進程進入臨界區
    • 一個非臨界區停止的進程必須不干涉其他進程
    • 不允許出現一個需要訪問臨界區的進程被無限延遲
    • 一個進程駐留在臨界區中的時間必須是有限的
    • 臨界區空閑時,任何需要進入臨界區的進程必須能夠立即進入

    滿足互斥的解決方案:

    1)硬件支持

    • 中斷禁用
      中斷禁用簡單說來就是在某一進程在臨界區執行過程中禁用中斷,不允許其他進程通過中斷打斷其執行。雖然這種方式可以保證互斥,但代價非常高,處理器被限制于只能交替執行程序,效率降低。另外不適用于多處理器環境。
    • 專用機器指令
      從硬件的角度提供一些機器指令,用于保證多個動作的原子性,通過適用這些具有原子性的指令來控制臨界區的訪問。比如提供符合以下邏輯的原子性指令:
      1. boolean testset(int i){  
      2.     if(i==0){  
      3.         i=1;  
      4.         return true;  
      5.     }else{  
      6.         return false;  
      7.     }  
      8. }  

      在控制臨界區的時候可以通過忙等待來保證只有一個進程停留在臨界區,偽代碼如下所示:
      1. int bolt;  
      2. void onlyOneThread(){  
      3.     while(!testset(bolt)){  
      4.         /*等待*/  
      5.     }  
      6.     /*臨界區*/  
      7.     bolt=0;  
      8. }  

      專用機器指令的優點是可以不限制處理器數量,也不限制臨界區的數量,但它的問題是使用了忙等待,消耗處理器時間。并且也存在饑餓和死鎖的問題

    2)信號量

    其原理是多個進程可以通過簡單的信號進行合作,一個進程可以被迫在某一個位置停止,直到它收到一個特定的信號,再重新被喚起工作。這種方式最大優點就是解決了忙等待的問題。其核心和機器指令類似,通過提供原子性信號量控制方法,一般情況下提供等待和喚起兩種操作原語,以較為簡單的二元信號量原語為例,兩種方法的偽代碼如下:

     

    1. void wait(semaphore s){  
    2.     if(s.value==1){  
    3.         s.value=0;  
    4.     }else{  
    5.         /*停止此線程,并把線程放入s的線程等待隊列(s.queue)里*/  
    6.     }  
    7. }  
    8. void signal(semaphore s){  
    9.     if(s.queue.size()==0){  
    10.         s.value=1;  
    11.     }else{  
    12.         /*從s的線程等待隊列(s.queue)里拿出一個線程,使其激活執行*/  
    13.     }  
    14. }  

     

    兩個方法的實現關鍵在于其原子性,當然也可以借助專用機器指令的方法來保障其原子性,畢竟這兩種方法的執行不長,使用忙等待也問題不大。

    再看互斥的問題,若使用信號量,則其具體實現如以下偽代碼所示:

     

    1. void onlyOneThread(){  
    2.     wait(s);  
    3.     /*臨界區*/  
    4.     signal(s);  
    5. }  

     

    3)管程

    信號量雖然解決了性能問題,但使得信號量的控制邏輯遍布在程序里,控制邏輯復雜以后很難整體上控制所有信號量。而管程的思路和面向對象類似,通過一個管程的概念把互斥和資源保護的細節封裝在管程的內部,外部程序只需對管程的正確使用就能保證避免并發問題,管程的特點如下:

    • 共享數據變量只能被管程的過程訪問
    • 一個進程通過調用管程的一個過程進入管程
    • 只能有一個進程在管程中執行,其他進程被掛起,等待進入管程

    4)消息傳遞

    消息傳遞是通過消息通信的方式進程之間相互配合,滿足互斥需求。這種方式最大好處就是可以運用與分布式環境。說到消息,抽象地看有兩種操作方式:send和receive。從同步方式上看分為阻塞和非阻塞兩種,其組合起來有以下 情況:

    • 阻塞send,阻塞receive。發送進程和接收進程都被阻塞,直到信息交付,同步性最好
    • 非阻塞send,阻塞receive。最為自然的一對組合
    • 非阻塞send,非阻塞receive。

    那么通過實現以上send和receive原語操作,就可達到互斥的目的,以下面偽代碼為例,其中receive為阻塞的,send為非阻塞的:

     

    1. void onlyOneThread(){  
    2.     receive(box,msg);  
    3.     /*臨界區*/  
    4.     send(box,msg);  
    5. }  

     

    小結

    以上是從操作系統的底層來看待并發問題,平常的開發過程一般不需要了解,但透過其原理,我們可以發掘一些解決并發問題的思路。只有真正了解并發產生的原因和操作系統采取的辦法,我們才能理解在更高一個層次(比如高級語言編程)為什么有那些控制和措施,為什么對一些代碼要做并發控制。

    posted on 2011-10-13 15:26 kxbin 閱讀(224) 評論(0)  編輯  收藏 所屬分類: java基礎
    你恨一個人是因為你愛他;你喜歡一個人,是因為他身上有你沒有的;你討厭一個人是因為他身上有你有的東西;你經常在別人面前批評某人,其實潛意識中是想接近他。

    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    常用鏈接

    留言簿(5)

    隨筆檔案

    文章分類

    文章檔案

    相冊

    收藏夾

    J2EE

    java技術網站

    Linux

    平時常去的網站

    數據庫

    電影網站

    網站設計

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲人成电影网站色www| 亚洲精品第一国产综合精品| 亚洲女子高潮不断爆白浆| 免费福利视频导航| 亚洲日韩在线视频| 99在线精品视频观看免费| 在线观看亚洲一区二区| 黄+色+性+人免费| 亚洲狠狠成人综合网| 国产成人高清精品免费软件| 朝桐光亚洲专区在线中文字幕| 国产在线a不卡免费视频| 日韩免费高清一级毛片| 国产亚洲精品资在线| 免费观看久久精彩视频| 91亚洲导航深夜福利| 国产h视频在线观看免费| 亚洲av永久中文无码精品综合| 国产极品粉嫩泬免费观看| 日韩毛片免费一二三| 久久精品亚洲综合| 一二三四免费观看在线视频中文版| 亚洲国产熟亚洲女视频| 亚洲国产精品一区二区三区久久| 中文毛片无遮挡高清免费| 亚洲综合一区二区精品久久| 成人在线免费观看| 精品久久久久久无码免费| 亚洲黄色在线电影| 免费无码又爽又刺激高潮| 美女巨胸喷奶水视频www免费| 亚洲伦理一区二区| 国产成人免费A在线视频| 成人黄网站片免费视频 | 久久精品国产亚洲AV果冻传媒| 成人免费在线看片| 成人国产网站v片免费观看 | 亚洲一区二区三区亚瑟 | 久久久久亚洲AV无码麻豆| 免费无码一区二区三区蜜桃大 | 国产成人亚洲综合一区|