多執行緒併發鎖
包括自旋鎖、互斥鎖、無鎖
POSIX介面
posix介面提供linux下執行緒操作庫,posix預設生成的執行緒佔用8M空間
-
pthread_create
執行緒建立函式pthread_create(pthread_t *th, const pthread_attr_t *attr, void *(* func)(void *), void *arg) // func是函式指標,是執行緒要呼叫的函式,arg是給呼叫函式傳的引數
鎖
互斥鎖mutex
執行緒試圖訪問被鎖資源時,執行緒會被阻塞。鎖釋放的時候,會喚醒所有該鎖上阻塞的執行緒。適用於鎖的內容較多的情況,比如佇列
pthread_mutex_t mutex; // 宣告互斥量
pthread_mutex_init(&mutex, NULL); // 預設初始化
ptherad_mutex_lock(&mutex); // 加鎖
ptherad_mutex_lock(&mutex); // 解鎖
自旋鎖spinlock
自旋鎖會一直去嘗試獲取鎖,相當於一個while
迴圈獲取。適用於鎖的內容很少比如變數,使用自選鎖,等待代價小於執行緒切換。此時cpu會發生空轉。
pthread_spinlock_t spinlock; // 宣告自旋鎖
pthread_spin_init(&spinlock, PTHERAD_PROCESS_PRIVATE); // 預設初始化
ptherad_spin_lock(&spinlock); // 加鎖
ptherad_spin_lock(&spinlock); // 解鎖
原子操作-無鎖
原子操作解決對應變數需要加鎖的問題,原子操作能夠將變數的指令變為單條CPU指令,這樣就能夠解決執行緒之間不同步的問題。原子操作的速度更快。
int inc(int* value, int add){
int old;
// volatile指示編譯器不要對變數進行最佳化
__asm__ volatile(
"lock; xaddl %2, %1"
: "=a" (old)
: "m" (*value), "a" (add)
: "cc", "memory"
);
}
CAS
cas指的是Compare-And-Swap
原子操作,能夠保證併發執行緒對共享資料安全訪問和修改。
實現思路
compare
用於檢測記憶體地址當前值是否與期望值相等,swap
如果期望值等於當前值,則將當前值作為新值。
實現方式
void cas(int *ptr, int expected, int desired) {
__asm__ volatile (
"lock; cmpxchg %2, %0\n" // 使用LOCK字首的cmpxchg指令
: "+m" (*ptr), "+a" (expected) // 運算元約束
: "r" (desired) // 運算元約束
: "memory" // 標記記憶體操作
);
}