天天看點

Linux中自旋鎖實作的基本原理之經典

目錄

​​一、自旋鎖基本簡介​​

​​二、自旋鎖和互斥鎖之間的差別​​

​​三、自旋鎖API函數​​

​​四、自旋鎖代碼實作​​

​​五、互斥鎖實作​​

​​運作結果:​​

​​總結:​​

線程:線程是程序資源配置設定的最小機關,每個程序都有的自己的main(主線程)

線程同步:多個線程按順序以此執行通路共享資源(資料)。

線程同步的必要性:防止多線程并發通路共享資料的時候出現資料混亂、不一緻 的問題。

線程同步的方法:互斥鎖、自旋鎖、條件變量....

Linux中自旋鎖實作的基本原理之經典

執行個體:建立兩個線程輪流計數

Linux中自旋鎖實作的基本原理之經典

#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;

}

一、自旋鎖基本簡介

自旋鎖本質上是一把鎖,在通路共享資源之前對自旋鎖進行上鎖,在通路完成後釋放自旋鎖(解鎖);

從實作方式上來說,互斥鎖是基于自旋鎖來實作的,是以自旋鎖相比較于互斥鎖更加底層。

二、自旋鎖和互斥鎖之間的差別

互斥鎖 自旋鎖
等待方式 阻塞(休眠) 自旋(不停申請)
效率 低(休眠、喚醒開銷大)
應用場景 程序上下文 中斷上下文
缺點
  1. 不能放在中斷服務函數中,易鎖死
  2. 開銷大
自旋占用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函數

  1. pthread_mutex_init(pthread_mutex_t*mutex,constpthread_mutexattr_t mutexattr) 初始化函數
  2. Pthread_mutex_lock(pthread_mutex_t *mutex) 加鎖函數
  3. 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;

}

運作結果:

不加鎖:

Linux中自旋鎖實作的基本原理之經典

總結:

繼續閱讀