muduo網路庫學習筆記(2):原子性操作
所謂原子操作是指不會被執行緒排程機制打斷的操作,這種操作一旦開始,就一直執行到結束,中間不會有任何 context switch (切換到另一個執行緒)。在多程式(執行緒)訪問資源時,能夠確保所有其他的程式(執行緒)都不在同一時間內訪問相同的資源。
C/C++ 中數值操作,如自加 (n++) 自減 (n- -) 及賦值 (n=2) 操作都不是原子操作。如果多執行緒程式需要使用全域性計數器,程式就需要使用鎖或者互斥量保證操作的安全性,對於較高併發的程式,這種做法會造成一定的效能瓶頸。
muduo網路庫對原子性操作的封裝有如下要點:
(1)gcc提供的原子操作
// 原子自增操作,返回的是更新前的值
type __sync_fetch_and_add (type *ptr, type value)
// 原子比較和交換(設定)操作
// 如果*ptr == oldval,就將newval寫入*ptr,第一個函式返回操作之前的值,第二個函式在相等並寫入的情況下返回true
type __sync_val_compare_and_swap (type *ptr, type oldval, type newval)
bool __sync_bool_compare_and_swap (type *ptr, type oldval, type newval)
// 原子賦值操作,將*ptr設為value並返回*ptr操作之前的值
type __sync_lock_test_and_set (type *ptr, type value)
使用這些原子性操作,編譯的時候需要加-march=cpu-type(如native,i386,pentium等等)
muduo原子性操作的程式碼中,就是利用gcc提供的原子操作來實現賦值、自加等原子性操作。
檔名:Atomic.h
T get()
{
return __sync_val_compare_and_swap(&value_, 0, 0);
}
// value++
T getAndAdd(T x)
{
return __sync_fetch_and_add(&value_, x);
}
T addAndGet(T x)
{
return getAndAdd(x) + x;
}
(2)volatile關鍵字
volatile的作用: 作為指令關鍵字,確保本條指令不會因編譯器的優化而省略,且要求每次直接讀值。簡單地說就是防止編譯器對程式碼進行優化。當要求使用volatile 宣告的變數的值的時候,系統總是重新從它所在的記憶體讀取資料,而不是使用儲存在暫存器中的備份。即使它前面的指令剛剛從該處讀取過資料。而且讀取的資料立刻被儲存。
(3)explicit關鍵字與隱式轉換
C++中的explicit關鍵字只能用於修飾只有一個引數的類建構函式,它的作用是表明該建構函式是顯示的, 而非隱式的,跟它相對應的另一個關鍵字是implicit, 意思是隱藏的,類建構函式預設情況下即宣告為implicit(隱式)。隱式轉換總是在我們沒有察覺的情況下悄悄發生,除非有心所為,隱式轉換常常是我們所不希望發生的。通過將建構函式宣告為explicit(顯式)的方式可以抑制隱式轉換。也就是說,explicit建構函式必須顯式呼叫。
通過一個例子來理解。
class Test1
{
public:
Test1(int n) { num = n; } // 普通建構函式
private:
int num;
};
class Test2
{
public:
explicit Test2(int n) { num = n; } // explicit(顯式)建構函式
private:
int num;
};
int main()
{
Test1 t1 = 12; // 成功,隱式呼叫其建構函式Test1(int n),再呼叫預設的拷貝建構函式
Test2 t2 = 12; // 編譯錯誤,不能隱式呼叫其建構函式
Test2 t3(12); // 成功,顯式呼叫其建構函式explicit Test2(int n);
return 0;
}
相關文章
- muduo網路庫學習筆記(1):Timestamp類筆記
- muduo網路庫學習筆記(3):Thread類筆記thread
- muduo網路庫學習筆記(14):chargen服務示例筆記
- muduo網路庫學習筆記(11):有用的runInLoop()函式筆記OOP函式
- muduo網路庫學習筆記(12):TcpServer和TcpConnection類筆記TCPServer
- muduo網路庫學習筆記(13):TcpConnection生命期的管理筆記TCP
- muduo網路庫學習筆記(10):定時器的實現筆記定時器
- muduo網路庫學習筆記(7):執行緒特定資料筆記執行緒
- muduo網路庫AtomicIntegerT原子整數類
- muduo網路庫學習筆記(9):Reactor模式的關鍵結構筆記React模式
- muduo網路庫學習筆記(8):高效日誌類的封裝筆記封裝
- muduo網路庫學習筆記(4):互斥量和條件變數筆記變數
- muduo網路庫學習筆記(5):執行緒池的實現筆記執行緒
- muduo網路庫學習筆記(6):單例類(執行緒安全的)筆記單例執行緒
- muduo網路庫學習之muduo_http 庫涉及到的類HTTP
- muduo網路庫學習之muduo_inspect 庫涉及到的類
- muduo網路庫學習筆記(15):關於使用stdio和iostream的討論筆記iOS
- muduo網路庫學習之EventLoop(七):TcpClient、ConnectorOOPTCPclient
- Symfony2學習筆記之資料庫操作筆記資料庫
- 【OCP學習筆記】配置網路環境 -- 2筆記
- 【學習筆記】網路流筆記
- [網路]NIO學習筆記筆記
- 網路流學習筆記筆記
- muduo網路庫學習之EventLoop(四):EventLoopThread 類、EventLoopThreadPool 類OOPthread
- docker學習筆記(2)- 倉庫Docker筆記
- muduo網路庫Timestamp類
- muduo網路庫使用心得
- muduo網路庫學習之EventLoop(六):TcpConnection::send()、shutdown()、handleRead()、handleWrite()OOPTCP
- RxJava2操作符學習筆記RxJava筆記
- JavaScript中的物件學習筆記(屬性操作)JavaScript物件筆記
- swoft 學習筆記之資料庫操作筆記資料庫
- muduo網路庫學習之EventLoop(一):事件迴圈類圖簡介和muduo 定時器TimeQueueOOP事件定時器
- muduo網路庫Exception異常類Exception
- muduo網路庫編譯安裝編譯
- Mybatis學習筆記 2:Mybatis 基本的CURD操作MyBatis筆記
- 學習筆記16:殘差網路筆記
- Mudo C++網路庫第五章學習筆記C++筆記
- Mudo C++網路庫第七章學習筆記C++筆記