日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

即时通讯软件 的无锁数组操作

發布時間:2025/3/15 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 即时通讯软件 的无锁数组操作 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

多線程下使用數組保存數據,必須先對數組進行加鎖,本文介紹?即時通訊軟件?的無鎖數組操作。

在之前的兩篇博客(線程安全的無鎖RingBuffer的實現,多個寫線程一個讀線程的無鎖隊列實現)中,分別寫了在只有一個讀線程、一個寫線程的情況下,以及只有一個寫線程、兩個讀線程的情況下,不采用加鎖技術,甚至原子運算的循環隊列的實現。但是,在其他的情況下,我們也需要盡可能高效的線程安全的隊列的實現。本文實現了一種基于循環數組和原子運算的無鎖隊列。采用原子運算(compare and swap)而不是加鎖同步,可以很大的提高運行效率。之所以用循環數組,是因為這樣在使用過程中不需要反復開辟內存空間,可以達到較好的效率。本文的實現參考了論文Implementing Lock-Free Queues所提到的方法。但是,在這篇論文中,作者并沒有給出具體的實現。本文的?即時通訊軟件?實現也和論文中的方法有所不同。本文的實現基于Windows操作系統,代碼在Visual Studio 2010下測試通過。

本文的實現基于compare and swap這個原子操作,簡寫為CAS。其原型為

long CAS(long* ptr, long old_value, long new_value).

其操作為,如果ptr所指向的變量和old_value相等,則將其置為new_value. 否則什么也不做。返回值為ptr所指向的變量。

本文提出的方法的基本原理如下。代碼會在其后附上。

首先,我們約定,有一個特殊的數值,叫做EMPTY,存入數組的所有數都不能是這個數值。在一開始,將整個buffer的值都初始化為EMPTY.

第二,以兩個變量,readCnt和writeCnt,來記錄讀和寫的次數。這兩個數模數組長度,就可以得到下一次讀和寫的位置。如果readCnt和writeCnt模buffer大小相等,則說明當前隊列為控;而如果在寫的位置不是EMPTY,則說明buffer已滿。

第三,也就是最重要的,線程同步的原理。在進行寫buffer操作時,首先通過CAS操作將buffer對應位置置為指定值,而writeCnt不變,因此其他線程無法在同樣的位置進行寫操作,這樣防止了其他寫線程的覆蓋。而由于此時writeCnt還沒有變,讀線程此時也無法讀該位置的數據,這樣防止了其他讀線程的沖突。接下來,第二步,則是通過CAS操作,將writeCnt加一??梢钥吹?#xff0c;代碼中在第一個CAS操作失敗的情況下,會執行一個增大writeCnt的原子操作。這樣做的目的是避免某個線程停掉導致其他所有線程都停掉。

而在進行寫操作時,首先通過判斷readCnt和writeCnt是否相等來判斷當前隊列是否已滿。這樣做的原因如前所述,是為了避免和寫線程之間的沖突。接下來,如果當前位置可以讀,則通過一個CAS操作將readCnt加一。這樣,其他讀線程就無法再讀這個位置。而由于這個位置值還不是EMPTY,其他寫線程也無法寫這個位置。接下來,在讀走數值之后,再通過CAS操作將buffer中的這個位置置為EMPTY. 此時,寫線程可以在這個位置寫入數據。

但是,這個?即時通訊軟件?實現其實還有點問題。如果讀線程比較多,例如,讀線程個數和數組長度一樣,就可能兩個讀線程同時讀同一個位置。這樣的讀沖突這個程序是無法避免的。另外,如果讀數據過程中有一個讀線程停掉了,那么其他線程在讀或者寫到這個位置時,也會被阻塞。

原文地址:http://www.nanshan.biz/thread-13079-1-1.html

 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的即时通讯软件 的无锁数组操作的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。