核心併發處理

2021-06-16 11:28:41 字數 1930 閱讀 2426

隨著硬體的發展,smp(對稱多處理器)已經很普遍,如果核心的排程機制是可搶占的,那麼smp和核心搶占是多執行緒執行的兩種場景。當多個執行緒同時訪問核心的資料結構時,我們就需要對其做序列化處理。

自旋鎖和互斥體

訪問共享資源的**區稱為臨界區。自旋鎖(spinlock)和互斥體(mutex, mutual exclusion)是保護核心臨界區的兩種基本機制。

自旋鎖可以確定在同時只有乙個執行緒進入臨界區。其他想進入臨界區域的執行緒(執行執行緒)必須不停的在原地打轉,知道第乙個執行緒釋放的自旋鎖。下面是spinlock的用法

#include /*初始化*/

spinlock_t _lock = spin_lock_unlocked;

/*上鎖*/

spin_lock(&_lock);

/*臨界區***/

/*釋放鎖*/

spin_unlock(&_lock);

互斥體與自旋鎖不一樣,當在臨界區外等待時,它不會不停的打轉,而是使當前的執行緒進入睡眠狀態。如果執行臨界區需要很長的時間,那麼互斥體更適合自旋鎖,這樣可是更好的利用cpu,而不是長時間在**打轉。

那對於這兩個怎麼取捨?

1.如果臨界區需要睡眠,只能使用互斥體,因為在獲得自旋鎖後進行排程、搶占以及在等待佇列上睡眠都是非法的。

2.由於互斥體會在面臨競爭的情況下將當前的執行緒置於睡眠狀態,因此,在中斷處理函式中只能使用自旋鎖。

下面是互斥體的使用方法

#include static define_mutex(_mutex);

mutex_lock(&_mutex);

/* 臨界區*/

mutex_unlock(&_mutex)

下面從四個案例中,討論核心併發保護。

1.程序上下文,單cpu,非搶占式核心

這種是最簡單的,不需要加鎖

2.程序和中斷上下文,單cpu,非搶占式核心

這種情況下,在保護臨界區的時候,僅僅只需要對中斷禁止。單cpu和非搶占式核心決定程序不會切換,可是在臨界區時,程序可能被中斷打斷,所以需要禁止中斷,也就是在進入臨界區時儲存中斷狀態,離開臨界區後恢復中斷狀態。

3.程序和中斷上下文,單cpu,搶占式核心

這種情況與2相比,核心可搶占,那麼就需要對臨界區加鎖來禁止核心的搶占,中斷還是和2一樣。

4.程序和中斷上下文,smp,搶占式核心

現在執行在smp機器上,而且你的核心配置了config_smp和config_preempt。在smp系統中,獲得自旋鎖時,僅僅本cpu的中斷被禁止,然後程序上下文和中斷處理函式可以在不同的cpu上進行,所以非本cpu的中斷處理函式需要等待本cpu上的程序上下文**推出臨界區。中斷上下文中需要使用spin_lock和spin_unlock。

原子操作

原子操作用於執行輕量級的,僅執行一次的操作,例如修改定時器、有條件的增加值,設定位等。原子操作可是實現操作的序列化,也就不許要加鎖處理。原子操作的時間取決了體系結構。

讀寫鎖自旋鎖的變體--讀寫鎖。如果每個執行單元在訪問臨界區的時候要麼是讀要麼是寫資料結構,但是他們都不會同時進行讀寫操作,那麼讀寫鎖很適合。讀寫鎖允許同一時候多個執行緒進入臨界區,但如果乙個寫執行緒進入臨界區,那麼其他的讀寫程序都必須等待。讀寫鎖使用方法:

rwlock_t _rwlock = rw_lock_unlocked;

read_lock(&_rwlock);

/* 臨界區***/

read_unlock(&_rwlock);

--------------------------------------

rwlock_t _rwlock = rw_lock_unlocked;

wirte_lock(&_rwlock);

/* 臨界區***/

wirte_unlock(&_rwlock);

併發程式設計核心 十二 併發類容器

jdk 5.0 以後提供了多種併發類容器來替代同步類容器從而改善效能。同步類容器的 狀態都是序列化的。他們雖然實現了執行緒安全,但是嚴重降低了併發性,在多執行緒環境時,嚴重降低了應用程式的吞吐量。併發類容器是專門針對併發設計的,使用 concurrenthashmap 來代替給予雜湊的傳 統的 ha...

Hibernate 處理併發

一 事務 指運算元據庫的乙個程式執行單無,這些操作要麼全部成功,要麼全部失敗以保證資料的完成性和統一性.二 多事務併發引起的問題 a 第一類丟失更新 撤銷乙個事務時把其它事務更新的資料也覆蓋了。for example 事務a 和b 同時訪問數 據data 如果事務b 更新了資料,但事務a執行了回滾操...

php redis TP處理併發

前兩天想自己研究php的併發問題,看到很多人都說用redis的佇列處理併發很好,所以自己也去研究了一下,下面用實際專案記錄一下自己的成果。基本思路是所有操作用過redis的佇列和集合處理併發 1.使用者搶購佇列 list user list 2.商品佇列 list goods list 3.訂單資訊...