linux同步機制

2021-06-12 05:13:58 字數 2999 閱讀 6433

一.併發控制

(1)自旋鎖

得不到資源,會原地打轉,直到獲得資源為止

定義自旋鎖

spinlock_t spin;
初始化自旋鎖

spin_lock_init(lock);
獲得自旋鎖

spin_lock(lock);獲得自旋鎖,如果能立即獲得,則馬上返回,否則自旋在那裡,直到該自旋鎖的保持者釋放

spin_trylock(lock);嘗試獲得自旋鎖,如果能立即獲得,它獲得並返回真,否則立即返回假,實際上,不再「在原地打轉」

釋放自旋鎖

spin_unlock(lock);與spin_trylock或者spin_lock配對使用
使用方法:

spinlock_t lock;

spin_lock_init(&lock);

spin_lock(&lock);//獲取自旋鎖,保護臨界區

...//臨界區

spin_unlock(&lock);//解鎖

eg:使用自旋鎖使裝置只能被乙個程序開啟

int ***_count=0;

static int ***_open(struct inode *inode, struct file *filp)

***_count++;

spin_unlock(&***_lock);

...return 0;

}

static int ***_release(struct inode *inode,struct file *filp)

(2)訊號量

得不到資源,會進入休眠狀態   

定義訊號量

struct semaphore sem;
初始化訊號量

void sema_init(struct semaphore *sem,int val);初始化並設定為val

void init_mutex(struct semaphore *sem);初始化並設定為1

void init_mutex_locked(struct semaphore *sem);初始化並設定為0

下面兩個巨集用於定義並初始化訊號量的「快捷方式」

declare_mutex(name);初始化並設定為1

declare_mutex_locked(name);初始化並設定為0

獲得訊號量

void down(struct semaphore *sem);會導致休眠,不能在中斷上下文使用

int down_interruptible(struct semaphore *sem);不會導致休眠,可在中斷上下文使用

使用down_interruptible()獲得訊號量時,常對返回值進行檢查

if(down_interruptible(&sem))

釋放訊號量

void up(struct semaphore *sem);釋放訊號量sem,喚醒等待者
使用方法:

declare_mutex(mount_sem);

down(&mount_sem);獲取訊號量,保護臨界區

...critical section //臨界區

...up(&mount_sem);//釋放訊號量

eg:使用訊號量實現裝置只能被乙個程序開啟

static declare_mutex(***_lock);//定義互斥鎖

static int ***_open(struct inode *inode,struct file *filp)

static int ***_release(struct inode *inode,struct file *filp)

總結:在多cpu中需要自旋鎖來互斥,當程序占用資源時間較長,使用訊號量。當所要保護的臨界區訪問時間較短,用自旋鎖,它節省了上下文切換的時間。

訊號量所保護的臨界區可包含可能引起阻塞的**,自旋鎖不能包含。阻塞意味著進行程序的切換,如果程序被切換出去後,另乙個程序企圖獲取本自旋鎖,死鎖會發生。

訊號量存在程序上下文,如果被保護的共享資源需要在中斷或軟中斷情況下使用,只能使用自旋鎖,如果一定要使用訊號量,只能通過down_trylock()方式進行,不能獲取就立即返回避免阻塞。

自旋鎖會導致死迴圈,鎖定期間不允許阻塞,鎖定的臨界區要小。

(3)互斥體

訊號量已經可以實現互斥的功能,但是mutex還是在linux中真實存在

定義並初始化

struct mutex my_mutex;

mutex_init(&my_mutex);

獲取互斥體

void fastcall mutex_lock(struct mutex *lock);

int fastcall mutex_lock_interruptible(strutct mutex *lock);

int fastcall mutex_trylock(struct mutex *lock);

釋放互斥體

void fastcall mutex_unlock(struct mutex *lock);
使用方法

struct mutex my_mutex;

mutex_init(&my_mutex);

mutex_lock(&my_mutex);

...//臨界資源

mutex_unlock(&my_mutex);

linux同步機制

原子操作 原子操作是由編譯器來保證的,保證乙個執行緒對資料的操作不會被其他執行緒打斷。當執行緒正在對乙個變數操作而這個操作過程不想被其他執行緒打斷時,可以用原子操作,原子操作結構體 atomic t 原子操作缺點 會阻塞優先順序很高的執行緒。自旋鎖 當乙個執行緒在讀寫乙個共享資源時,加上自旋鎖,其他...

linux同步機制

1 自旋鎖 獲得自旋鎖之後禁止核心搶占,但可以被中斷上半部打斷。執行於中斷上下文 單cpu不可搶占核心 空操作 單cpu可搶占核心 禁止核心搶占,不發生自旋 多cpu可搶占核心 禁止核心搶占 自旋 2 互斥鎖 核心可以搶占,可以被其他程序搶占,執行於程序上下文 3 讀寫鎖 4 順序鎖 對讀寫鎖的一種...

linux 2 6同步機制

作業系統的同步機制是老話題了,不過技術的東西放久不用了就容易忘記,在這裡就訊號量為大家整理一下思緒。在linux系統中,訊號量是一種可以睡眠的鎖。如果程序a希望占有乙個正在被程序b使用的訊號量時,程序a會被推入等待佇列,然後睡眠。直到程序b將持有的訊號量釋放,處於等待佇列中的程序a才會被喚醒,並獲得...