TAS 指令與PostgreSQL spin lock
TAS: 指Test-And-Set,它是一個原子操作,修改記憶體的值,並返回原來的值。當一個程式P1對一個記憶體位置做TAS操作,不允許其它程式P2對此記憶體位置,再做TAS操作。
P2必須等P1操作完成後,再做TAS操作。以下是一個簡單的鎖,透過TAS來實現:
volatile int lock = 0; void Critical() { while (TestAndSet(&lock) == 1); critical section // only one process can be in this section at a timelock = 0 // release lock when finished with the critical section}
假設lock原來的值為“0”,當P1去做申請lock時,能獲取得到鎖。而此時P2再去申請鎖時,必須spin,因為此時lock的值已經被P1修改為“1”了。
用TAS來實現spin lock,此處要注意volatile的使用。volatile表示這個變數是易失的,所以會編譯器會每次都去記憶體中取原始值,而不是直接拿暫存器中的值。
這避免了在多執行緒程式設計中,由於多個執行緒更新同一個變更,記憶體中和暫存器中值的不同步而導致變數的值錯亂的問題。另外,也會影響編譯器的最佳化行為。
在PostgreSQL中,spin lock的實現包含在spin.c和s_lock.c兩個檔案中。在不支援TAS的情況下,PG會使用PGSemaphores來實現 spin lock。
1.使用semaphore實現
其中spin.c主要封裝了spin lock用PGSemaphores來實現的介面,跟硬體保持獨立。PGSemaphore是使用OS底層的semaphore來實現的,PG對其做了封裝,提供了PG系統內部統一的semaphore操作介面。
PG的用PGSemaphore結構體表示PG 自身的semaphore訊號,並將相關操作封裝在sembuf中,傳遞給底層OS。
PG semaphore lock操作:
PG semaphore結構體:
操作封裝:
semop操作:
底層OS實現呼叫,OS宣告在/usr/sys/include/sem.h中:
從上面可以看出,PG的semaphore實現非常清晰,而且與OS底層的呼叫關係也很明瞭。
2.使用TAS指令實現
而s_lock.c 則用TAS方式了spin lock,與硬體相關。在PG原始碼中,使用s_lock函式來申請spin lock:
int s_lock(volatile slock_t *lock, const char *file, int line)
tas操作如下:
PG使用了自適應演算法,來決定spin的次數和每次spin後,sleep的時間。
spins_per_delay:spin多少次後,開始sleep。預設為100,最大值為1000,最小值為10。
cur_delay:當前sleep的時間,最大值為1000,最小值為1。單位為毫秒。
spins_per_delay的值,基本上不變;但是cur_delay的值為當前值1倍和2倍之間變動。因此,spin delay次數越多,sleep時間會越長。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30088583/viewspace-1512121/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- PostgreSQL spin 與 lwlockSQL
- spin_lock、spin_lock_irq、spin_lock_irqsave區別【轉】
- 【轉】spin lock 和mutexMutex
- Pthreads並行程式設計之spin lock與mutex效能對比分析thread並行行程程式設計Mutex
- 硬體對同步的支援-TAS和CAS指令
- Linux核心同步機制之(五):Read Write spin lock【轉】Linux
- PostgreSQL DBA(77) - Locks(Lock Monitoring)SQL
- LightDB/PostgreSQL等待事件 Lock transactionidSQL事件
- MySQL 8.0 Reference Manual(讀書筆記74節--Spin Lock Polling & Purge Configuration)MySql筆記
- PostgreSQL 原始碼解讀(220)- Locks(LOCK Struct)SQL原始碼Struct
- 【MySQL】select for update 的Row Lock 與Table LockMySql
- PostgreSQL之鎖監控指令碼SQL指令碼
- 終於徹底搞清楚了spin-lock 之一次CPU問題定位過程總結
- 四、Synchronized與Lock原理synchronized
- synchronized與Lock的區別synchronized
- synchronized 與 Lock 的對比synchronized
- 初識Lock與AbstractQueuedSynchronizer(AQS)AQS
- Latch 與 Lock 的區別
- oracle dead lock與效能Oracle
- mysql表鎖與lock tablesMySql
- PostgreSQL 原始碼解讀(222)- Locks(Lock Manager Internal Locking)SQL原始碼
- Lock 介面與 AQS 同步器AQS
- synchronized 與 Lock 的那點事synchronized
- synchronized與Lock的區別與使用詳解synchronized
- MFC NumericUpDown Spin控制元件 CSpinButtonCtrl控制元件
- No Response from the Server, Does it Hang or Spin? (Doc ID 68738.1)Server
- PostgreSQL:啟動與停止SQL
- PostgreSQL與MySQL比較MySql
- mysql metadata lock原理與實現MySql
- bash shell指令碼訪問PostgreSQL的三種方式指令碼SQL
- Large result cache can cause sessions to spin -instance to hangSession
- PostgreSQL TPROC-C基準測試:PostgreSQL 12與PostgreSQL 13效能對比SQL
- Postgresql與MySQL的區別MySql
- 聊一聊Greenplum與PostgreSQLSQL
- Postgresql 備份與恢復SQL
- postgresql 優化與維護SQL優化
- 《PostgreSQL》 索引與最佳化SQL索引
- TAS5805MPWPR 攜式音訊應用—數字音訊技術音訊