目錄
一、自旋鎖基本簡介
二、自旋鎖和互斥鎖之間的差別
三、自旋鎖API函數
四、自旋鎖代碼實作
五、互斥鎖實作
運作結果:
總結:
線程:線程是程序資源配置設定的最小機關,每個程序都有的自己的main(主線程)
線程同步:多個線程按順序以此執行通路共享資源(資料)。
線程同步的必要性:防止多線程并發通路共享資料的時候出現資料混亂、不一緻 的問題。
線程同步的方法:互斥鎖、自旋鎖、條件變量....
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5SMzUjN1MWZmFWOhZmYmZWMzYzX2QTM0ETMzEzLclDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
執行個體:建立兩個線程輪流計數
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<pthread.h> int q_cont; //計數值 long loops; //計數次數 void *task(void *arg) { long num=(long)arg; int j_cont=0; int i; for(i=0;i<num;i++) //單線程循環loops次 { //計數 j_cont=q_cont; j_cont++; q_cont=j_cont; } pthread_exit(NULL); } int main(int aegc,char *argv[]) { int i; pthread_t tid1,tid2; loops=atoi(argv[1]); //建立線程 pthread_create(&tid1,NULL,task,(void *)loops); pthread_create(&tid2,NULL,task,(void *)loops); //等待線程結束 pthread_join(tid1,NULL); pthread_join(tid2,NULL); //列印次數 printf("q_cont=%d\r\n",q_cont); return 0; } |
一、自旋鎖基本簡介
自旋鎖本質上是一把鎖,在通路共享資源之前對自旋鎖進行上鎖,在通路完成後釋放自旋鎖(解鎖);
從實作方式上來說,互斥鎖是基于自旋鎖來實作的,是以自旋鎖相比較于互斥鎖更加底層。
二、自旋鎖和互斥鎖之間的差別
互斥鎖 | 自旋鎖 | |
等待方式 | 阻塞(休眠) | 自旋(不停申請) |
效率 | 低(休眠、喚醒開銷大) | 高 |
應用場景 | 程序上下文 | 中斷上下文 |
缺點 |
| 自旋占用CPU資源,不适用于長時間等待 |
三、自旋鎖API函數
1、pthread_spin_init() 初始化函數
原型:int pthread_spin_init(pthread_spinlock_t *lock ,int pshared);
參數:pthread_spinlock_t *lock pthread_spinlock_t 定義的鎖
int pshared PTHREAD_PROCESS_PRIVATE
PTHREAD_PROCESS_SHARED
PTHREAD_PROCESS_PRIVATE
PTHREAD_PROCESS_SHARED
2、pthread_spin_lock(pthread_spinlock_t *lock) 加鎖函數
3、pthread-spin_unlock(pthread_spinlock_t *lock) 解鎖函數
4、pthread_spin_destroy(pthread_spinlock_t *lock) 摧毀鎖函數
補充:
pthread_spin_trylock(pthread_spinlock_t *lock) 加鎖函數
函數對自旋鎖進行加鎖,如果未能擷取到鎖,就立刻傳回錯誤,錯誤碼為 EBUSY。
互斥鎖API函數
- pthread_mutex_init(pthread_mutex_t*mutex,constpthread_mutexattr_t mutexattr) 初始化函數
- Pthread_mutex_lock(pthread_mutex_t *mutex) 加鎖函數
- Pthread_mutex_unlock(pthread_mutex_t *mutex) 解鎖函數
4、Pthread_mutex_destroy(pthread_mutex_t *mutex) 摧毀鎖
四、自旋鎖代碼實作
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<pthread.h> int q_cont; //計數值 long loops; //循環計數次數 pthread_spinlock_t spin; void *task(void *arg) { long num=(long)arg; int j_cont=0; int i; for(i=0;i<num;i++) //循環loops次 { //加鎖 pthread_spin_lock(&spin); j_cont=q_cont; j_cont++; q_cont=j_cont; //解鎖 pthread_spin_unlock(&spin); } pthread_exit(NULL); } int main(int aegc,char *argv[]) { int i; pthread_t tid1,tid2; loops=atoi(argv[1]); //初始化自旋鎖 pthread_spin_init(&spin,PTHREAD_PROCESS_PRIVATE); //建立線程 pthread_create(&tid1,NULL,task,(void *)loops); pthread_create(&tid2,NULL,task,(void *)loops); //等待線程 pthread_join(tid1,NULL); pthread_join(tid2,NULL); //摧毀鎖 pthread_spin_destroy(&spin); printf("q_cont=%d\r\n",q_cont); return 0; } |
五、互斥鎖實作
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<pthread.h> int q_cont; //計數值 long loops; //計數次數 pthread_mutex_t lock; void *task(void *arg) { long num=(long)arg; int j_cont=0; int i; for(i=0;i<num;i++) //單線程循環loops次 { //加鎖 pthread_mutex_lock(&lock); //計數 j_cont=q_cont; j_cont++; q_cont=j_cont; //解鎖 pthread_mutex_unlock(&lock); } pthread_exit(NULL); } int main(int aegc,char *argv[]) { int i; pthread_t tid1,tid2; loops=atoi(argv[1]); //互斥鎖初始化 pthread_mutex_init(&lock,NULL); //建立線程 pthread_create(&tid1,NULL,task,(void *)loops); pthread_create(&tid2,NULL,task,(void *)loops); //等待線程結束 pthread_join(tid1,NULL); pthread_join(tid2,NULL); //摧毀鎖 pthread_mutex_destroy(&lock); //列印次數 printf("q_cont=%d\r\n",q_cont); return 0; } |
運作結果:
不加鎖: