兩線程間無鎖進行資料同步

2021-06-09 01:50:58 字數 1153 閱讀 7870

執行緒間資料同步常用的方法就是加鎖,但會引發程式掛起延遲的現象,在實時性較高的程式中不可取。

而無鎖程式設計也有很多方法,如

文章中,對多不同層級的資料同步方法有著詳細的介紹。

據其介紹,兩線程間環形快取區無鎖的方法能夠比較好的解決讀寫問題。

我採用環形佇列作為環形緩衝區的資料結構。

環形佇列的實現方式也可分為線性和鏈式。對資料個數大小已知或在某個範圍內控的情況,採用線性結構的佇列,效率比較高;而對資料數量未知的情況,可採用鏈式結構。

在組織資料結構時,應小心以下幾點:

1. 此解決方法適用於兩線程間的讀寫問題;

2. 讀者與寫者必須先讀寫資料,後更新索引;

3. 讀者執行緒只操作(更改)頭索引,寫者執行緒只操作(更改)尾索引,不能某執行緒同時操作兩個索引。

4. 注意讀寫可能會發生溢位overflow的狀況。讀寫前,進行判空與滿的操作,若滿,則需要丟資料。

5. 對線性環形佇列的容量,可以設定為2^n,目的是提高迴圈操作取模%的效率(索引是單向遞增的情況)。

對於溢位丟資料的情況,改進方法:

1. 對溢位的資料另外儲存,然後加鎖同步。這是個解決方法,但本身違背了原來無鎖的初衷。

2. 採用鏈式結構作為緩衝區,資料操作頻繁情況下,空間與時間的效率可能較低。嵌入式下,資料結構盡量有乙個大小的限制,畢竟資源是有一定限制的,特別是在多個大的應用程式同時執行的狀況下。

3. 兩個佇列,乙個線性,乙個鏈式,非溢位時使用線性佇列處理資料;在溢位時,採用鏈式儲存溢位的資料。夠麻煩吧,效率與複雜度有時就是矛盾。

4. 丟就丟了吧,多測試丟包的情形,設定乙個合理的大小,儘量減少丟資料的情況,不過,偶爾發生時,丟就丟了吧。

以上,僅僅是對兩線程間資料傳遞的場景,無需加鎖。若是多個執行緒同時讀資料,就需要對讀資料時,更改佇列的**加保護,加互斥器;同理,若是多個執行緒寫資料,也需要對寫佇列的**加互斥量。否則,仍會可能由於執行緒競爭造成資料被破壞的情況。 當然,寫資料,和讀資料 採用不同的互斥器。

今天跟幾個做嵌入式的同事討論,嵌入式下能否使用c++ stl,他們都不怎麼應用stl的,原因是資源畢竟有限。

不過看網上的討論,很多人還是支援使用stl,在編譯器支援的情況下,提高開發效率。

在使用時,盡量注意下資源的使用情況,比如資料結構的大小有個限制,不要無限增大。(可能,隨著軟硬體資源的擴充套件,這種情況根本不用考慮了)

如何進行資料同步

建立資料庫的鏈結 create database link dblink test connect to 需要鏈結的資料庫的名字 identified by 密碼 using 這個鏈結的別名 建立物化檢視用於同步資料 create materialized view test test是同步過來的實...

rsync sersync進行資料同步備份

sersync功能多 支援配置檔案管理 真正的守護程序 可以對失敗檔案定時重傳 第三方的http介面 預設多執行緒 cdn更新 sercver 192.168.138.131 配置與之前的一樣 client 192.168.138.132 網查參考了很多人家的部落格,然後總結寫出來的 客戶端的配置 ...

執行緒間同步機制 互斥鎖

互斥以排他方式防止共享資料被併發修改。互斥量從本質來說是一把鎖,是乙個二元變數,其狀態為開鎖 允許0 和上鎖 禁止1 在訪問共享資源前對互斥量進行設定 加鎖 在訪問完成後釋放 解鎖 互斥量。1 在訪問該資源前,首先申請該互斥鎖,如果該互斥鎖處於開鎖狀態,則申請到該鎖物件,並立即占有該鎖 使該鎖處於鎖...