轉 Linux kernel 無鎖佇列

2022-07-31 09:15:11 字數 1298 閱讀 8412

struct kfifo ;

struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock)   

buffer = kmalloc(size, gfp_mask);   

if (!buffer)   

return err_ptr(-enomem);   

ret = kfifo_init(buffer, size, gfp_mask, lock);   

if (is_err(ret))   

kfree(buffer);   

return ret;   

}   

這裡值得一提的是,kfifo->size的值總是在呼叫者傳進來的size引數的基礎上向2的冪擴充套件,這是核心一貫的做法。這樣的好處不言而喻--對kfifo->size取模運算可以轉化為與運算,如下:

kfifo->in % kfifo->size 可以轉化為 kfifo->in & (kfifo->size – 1)

在kfifo_alloc函式中,使用size & (size – 1)來判斷size 是否為2冪,如果條件為真,則表示size不是2的冪,然後呼叫roundup_pow_of_two將之向上擴充套件為2的冪。 這些都是很常用的技巧,只不過大家沒有將它們結合起來使用而已,下面要分析的__kfifo_put和__kfifo_get則是將kfifo->size的特點發揮到了極致。

3. __kfifo_put和__kfifo_get,巧妙的入隊和出隊操作,無鎖併發

__kfifo_put是入隊操作,它先將資料放入buffer裡面,最後才修改in引數;__kfifo_get是出隊操作,它先將資料從buffer中移走,最後才修改out。你會發現in和out兩者各司其職。計算機科學家已經證明,當只有乙個讀經程和乙個寫執行緒併發操作時,不需要任何額外的鎖,就可以確保是執行緒安全的,也即kfifo使用了無鎖程式設計技術,以提高kernel的併發。

下面是__kfifo_put和__kfifo_get的**

[cpp]view plain

copy

print

?unsigned int __kfifo_put(struct kfifo *fifo,   

unsigned char *buffer, unsigned int len)   

unsigned int __kfifo_get(struct kfifo *fifo,   

unsigned char *buffer, unsigned int len)   

mySQL無鎖佇列 go 無鎖佇列

無鎖佇列適用場景 兩個執行緒之間的互動資料,乙個執行緒生產資料,另外乙個執行緒消費資料,效率高 缺點 需要使用固定分配的空間,不能動態增加 減少長度,存在空間浪費和無法擴充套件空間問題 package main import fmt reflect strings time type loopque...

莫隊演算法 無修

無修的莫隊演算法,是用來處理沒有修改操作的序列的詢問操作的離線演算法 莫隊演算法的本質是什麼?大概就是分塊加上乙個大家可能都想到過的東西 也就是乙個區間1l r,其左邊的區間2 l 1 r 1 的和轉化到區間1的和只需要o 1 的時間複雜度 也就是sum 1 su m2 a r a l 1 sum1...

無鎖環形佇列

環形一讀一寫佇列中,不需要擔心unsigned long溢位問題,因為溢位後自動回歸,相減值還會保留。示例一 注 max count 必須為 2 的指數,即 2,4,8,16.佇列尺寸 define max count 4096 define max mask 4095 max count 1 變數...