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

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

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

    一江春水向東流

    做一個有思想的人,期待與每一位熱愛思考的人交流,您的關注是對我最大的支持。

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      44 隨筆 :: 139 文章 :: 81 評論 :: 0 Trackbacks
    使用線程編寫程序需要技巧,而多線程的程序中的bug非常難以跟蹤、調試,因為這些bug經常是難以再現的。

    競爭條件

    當一個線程訪問一個數據結構的時候,另一個線程也訪問同一個數據結構,這時就出現了競爭條件——兩個線程(也可能是多個)競爭對同一個資源的訪問。
    當其中一個線程處理到一部分的時候,另外的線程可能進入了對同一數據的處理,而且出于調度的原因,它運行的比前一個更快;這時,同樣的處理可能就出現了多次。
    例如,一個代表任務列表的單向鏈表(隊列),一個線程從當前元素中讀出了下一個任務,并發現下一個任務不是空,準備將此一個任務置為NULL并執行任務;這時,調度使得這個線程停下來,另一個線程也從當前元素中讀出了下一個任務,當然下個任務仍然不是空值,這個線程也將要執行下一個任務。這樣,在某些不幸的情況下,這個任務被執行了兩次。
    更為不幸的情況下,執行任務的過程中線程被中斷,此時另一個線程釋放了任務的內存,那么執行中的線程會導致段錯誤。
    在比較“幸運”的情況下,這些事情可能從來也不發生;但是當程序運行在負荷很高的系統中時,這個bug就會凸現出來。

    互斥鎖
    為了排除競爭條件的影響,應該使一些操作變成“原子的”——這些操作既不能分割也不能中斷。
    當一個線程鎖定了互斥鎖后,其他線程也要求鎖定這個互斥鎖的時候,就會被阻塞;直到前面的線程解除鎖定后,其他線程才可以解除阻塞恢復運行。
    GNU/Linux保證線程在鎖定互斥鎖的過程中不會發生競爭條件,只有一個線程可以鎖定互斥鎖,其他線程的鎖定請求都會被阻塞。

    創建互斥鎖(Mutex),需要:
    `創建一個pthread_mutex_t類型的變量,將其指針傳入函數pthread_mutex_init中;該函數的第二個參數是指向一個mutex屬性對象(這個對象用來指定mutex的屬性)的指針。mutex對象只能初始化一次。
    `更簡單的辦法是,使用PTHREAD_MUTEX_INITIALIZER來獲得默認屬性的mutex對象:
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

    使用mutex:
    `調用pthread_mutex_lock函數,如果mutex對象未被鎖定,則此函數立即返回;如果已被鎖定,則此函數阻塞此線程的執行,直到mutex被解除鎖定。
    `每次解除鎖定后,只有一個線程可以解除阻塞恢復執行,其他調用線程都會繼續阻塞。選定的解除阻塞的線程是不可預知的。
    `調用pthread_mutex_unlock函數,可以解除調用線程對mutex對象的鎖定。在鎖定mutex的線程中,必須調用此函數以解除鎖定。

    mutex提供了解決競爭條件的方案,但是它帶來了一種新的bug——死鎖deadlock)。
    所謂死鎖,就是說一個線程在等待永遠不會發生的條件。
    一個簡單的死鎖:一個線程鎖定它自己已經鎖定的mutex。這時程序的表現依賴于mutex的類型:
    `快速排他鎖(fast mutex)——導致死鎖。
    `遞歸排他鎖(recursive mutex)——不導致死鎖。同一個線程可以安全的多次鎖定同一個已鎖定的mutex,但是鎖定的次數會被記錄下來,該線程還必須調用相應次數的pthread_mutex_unlock才能真正解除對mutex的鎖定。
    `檢錯排他鎖(error-checking mutex)——GNU/Linux視此操作為死鎖,但是對鎖定的mutex調用pthread_mutex_lock函數,函數立即返回錯誤碼EDEADLK。

    mutex的鎖定函數會阻塞,有時需要一個不阻塞就能知道mutex是否已鎖定的函數,以在發現mutex已鎖的情況下去完成其他工作并在以后再來檢查。這樣的函數是:
    pthread_mutex_trylock
    如果傳入的mutex已經被其他線程鎖定,那么這個函數返回錯誤碼EBUSY;如果未被鎖定,此函數會鎖定mutex,并返回0。這個函數不會阻塞。
    posted on 2008-02-15 10:15 allic 閱讀(1411) 評論(0)  編輯  收藏 所屬分類: C/C++
    主站蜘蛛池模板: 久久九九亚洲精品| 18亚洲男同志videos网站| 免费三级毛片电影片| 99麻豆久久久国产精品免费| 亚洲αⅴ无码乱码在线观看性色 | 亚洲成AV人片在线播放无码| 污污网站18禁在线永久免费观看| 亚洲第一区视频在线观看| www.亚洲精品.com| 午夜毛片不卡免费观看视频| 日本XXX黄区免费看| 在线观看的免费网站无遮挡| 亚洲AV性色在线观看| 亚洲ts人妖网站| 亚洲成a人片7777| 亚洲精彩视频在线观看| 成人免费无码精品国产电影| 国产香蕉九九久久精品免费| 24小时日本韩国高清免费| 国产亚洲精品美女久久久久| 亚洲乱亚洲乱妇24p| 亚洲人精品亚洲人成在线| 亚洲午夜电影在线观看高清| 亚洲人成电影福利在线播放| 亚洲av无码潮喷在线观看 | 亚洲日本在线观看| 亚洲va中文字幕无码久久不卡| 免费看国产精品3a黄的视频| 亚洲一级毛片免费看| 120秒男女动态视频免费| 日日麻批免费40分钟无码| 国产成人人综合亚洲欧美丁香花| 精品久久久久久亚洲| 亚洲日韩激情无码一区| 亚洲欭美日韩颜射在线二| 亚洲精品中文字幕无码蜜桃| 亚洲国产精品无码专区影院| 亚洲av午夜福利精品一区| 亚洲av高清在线观看一区二区| 免费成人福利视频| 四虎永久在线观看免费网站网址|