在 box64 執行的過程中就已經使用了需多 lock ,如果測量期行為的程式也需使用 lock 的話無疑會讓執行過程更複雜,因此務必使用 lock-free
大家都知道要避免 race condition, 但 race condition 會發生在哪些情境呢? 發生了會怎樣呢?
多個生產者之間:
生產者與消費者:
多個消費者之間:
於是我們需要變更原本執行緒的程式邏輯,當 atomic 操作不能成功時,就重來,直到 RMW 一類的 atomic 操作成功為止
並不是「沒有用到 mutex lock」 就是 lock-free, 而是「能保證至少有一個執行緒在進展」才叫 lock-free.
從論文中可以窺探到 lock-free 的秘密,即將步驟分成 logical
和 physical
,而 logical
會通知所有執行緒
best-case and worst-case usage scenarios for locks ->
「裡面放的東西一樣」不能確保「剛剛到現在都沒有人動過裡面的東西」
memory_order_relaxed
memory_order_consume
memory_order_acquire
memory_order_release
memory_order_acq_rel
memory_order_seq_cst
ringbuf_shm
考量因素
atomic + while + 預約 -> how ?
結構 :
MPSC
測試程式:
考量因素:
什麼意思?這是 linked-list 的意思嗎?其實不然
生產者會更新執行的次數 producer_count
並將 in
push 到 Queue 中,然而 test_producer
是如何做到 lock-free 呢? 如何確保對共享 queue 的讀-修改-寫(read-modify-write)沒有被打擾呢?
THREAD_COUNT
的用意為何? 跟 PRODUCER_COUNT
的差別是?
THREAD_COUNT
是指執行過程中所用到的執行緒數量上限,即consume_count
(消費者執行的次數) +producer_count
(生產者執行的次數) <=THREAD_COUNT
可以注意到 psuh 分成兩個步驟:
a. 找到要「接上」的 node (相當於對所有執行緒預告了未來的 tail)
b. 「接上」node
那如果失敗呢?
步驟 a 不一定要直接接著步驟 a ,兩步驟間可以穿插其他執行緒的步驟,假設有兩個生產者的執行緒同時要加入節點
atomic_exchange | 成功 | 失敗 |
---|---|---|
old_tail |
||
q->tail |
atomic_store | 成功 | 失敗 |
---|---|---|
old_tail->next |
||
q->head |