Linux的同步和非同步

2021-08-17 14:34:48 字數 3910 閱讀 5580

一.併發控制

(1)自旋鎖

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

定義自旋鎖

[html]view plain

copy

spinlock_t spin;  

初始化自旋鎖

[html]view plain

copy

spin_lock_init(lock);  

獲得自旋鎖

[html]view plain

copy

<

span

style

="white-space:pre;"

>

span

>

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

spin_trylock(lock);嘗試獲得自旋鎖,如果能立即獲得,它獲得並返回真,否則  

立即返回假,實際上,不再「在原地打轉」  

釋放自旋鎖

[html]view plain

copy

<

span

style

="white-space:pre;"

>

span

>

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

使用方法:

[html]view plain

copy

spinlock_t lock;  

spin_lock_init(&lock);  

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

...//臨界區  

spin_unlock(&lock);//解鎖    

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

[html]view plain

copy

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)訊號量

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

定義訊號量

[html]view plain

copy

struct semaphore sem;  

初始化訊號量

[html]view plain

copy

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

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

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

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

[html]view plain

copy

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

declare_mutex_locked(name);初始化並設定為0                                         獲得訊號量  

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

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

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

[html]view plain

copy

if(down_interruptible(&sem))  

釋放訊號量

[html]view plain

copy

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

使用方法:

[html]view plain

copy

declare_mutex(mount_sem);  

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

...  

critical section //臨界區  

...  

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

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

[html]view plain

copy

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中真實存在

定義並初始化

[html]view plain

copy

struct mutex my_mutex;  

mutex_init(&my_mutex);  

獲取互斥體

[html]view plain

copy

void fastcall mutex_lock(struct mutex *lock);  

int fastcall mutex_lock_interruptible(strutct mutex *lock);  

int fastcall mutex_trylock(struct mutex *lock);  

釋放互斥體

[html]view plain

copy

void fastcall mutex_unlock(struct mutex *lock);  

使用方法

[html]view plain

copy

struct mutex my_mutex;  

mutex_init(&my_mutex);  

mutex_lock(&my_mutex);  

...//臨界資源  

mutex_unlock(&my_mutex);  

同步和非同步

同步執行模式 所謂同步執行模式,是指語句在同步執行模式下,將始終保持對程式流的控制,直至 程式結束。如查詢操作,客戶機上的應用程式在向伺服器發出查詢操作的指令後,將 一直等待伺服器將查詢結果返回客戶機端,然後才繼續進行下一步操作。眾所周知,應用程式要從乙個大表中刪除所有的記錄將是非常耗時的,如果應用...

同步和非同步

同步互動 是指傳送乙個請求,需要等待返回,然後才能傳送另乙個請求,是乙個需要等待的過程。非同步互動 是指傳送乙個請求,不需要等待,隨時可以在傳送另乙個請求,是乙個不需要等待的過程。同步可以避免出現死鎖,讀髒資料的發生,一般共享某一資源的時候用,如果每個人都有修改許可權,同時修改乙個檔案,有可能使乙個...

同步和非同步

同步執行模式 所謂同步執行模式,是指語句在同步執行模式下,將始終保持對程式流的控制,直至 程式結束。如查詢操作,客戶機上的應用程式在向伺服器發出查詢操作的指令後,將 一直等待伺服器將查詢結果返回客戶機端,然後才繼續進行下一步操作。眾所周知,應用程式要從乙個大表中刪除所有的記錄將是非常耗時的,如果應用...