91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

crossbeam-epoch中基于epoch的無鎖垃圾收集原理是什么

發布時間:2021-12-27 09:26:15 來源:億速云 閱讀:241 作者:柒染 欄目:大數據

這篇文章給大家介紹crossbeam-epoch中基于epoch的無鎖垃圾收集原理是什么,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

crossbeam提供了一個基于epoch的“垃圾收集”(epoch based reclamation)庫。首先來簡單的說一下這一垃圾回收的原理。

基于epoch的“垃圾回收”

這一算法主要在Keir Fraser的  博士論文  中有涉及。我們從之前無鎖并發棧的簡單實現中看到,并發環境中的數據結構的容器(比如包含了出棧元素的那個節點),會在一個線程中完成它的使命然后準備被釋放。但是這個時候可能還有其他線程還持有其快照(主要是為了進行CAS)。不過不會再有新的線程還會繼續取得其快照了。那么只要等到所有對該容器取得快照的線程都完成操作,就可以安心的釋放這個容器了。
這一算法需要:
  1. 一個全局的epoch計數器
  2. 每個線程有一個本地的epoch計數器
  3. 一個全局列表記錄每個epoch產生的垃圾
  4. 標示線程是否活躍的標示符
算法大概是這樣的:當一個線程需要對某個數據結構操作時,它先將自己的標識符設置為活躍,然后將本地epoch計數器更新為全局epoch計數器。而如果線程需要從數據結構中刪除一個節點,它會把該節點加入當前epoch的垃圾列表。當線程完成對數據結構的操作時,線程將自己標記為不活躍。然后當需要收集垃圾的時候,一個線程會遍歷所有線程并檢查是否所有活躍的線程的epoch都和當前全局的epoch相同,如果是那么全局epoch計數將會+1,同時2個epoch前的垃圾可以被回收。
事實上,當處于epoch N+2的時候,由于所有對數據進行操作(活躍)的線程都在epoch N+1之后,可以安全的清理epoch N的垃圾列表。

crossbeam-epoch的API

Guard

使用  pin  可以產生  Guard  ,這將當前線程標識為活躍
    
  
  
  
use crossbeam_epoch as epoch;
let guard = &epoch::pin();
     
     
defer_destroy  則將數據放入垃圾列表,等待2個epoch之后就可以被清理了
    
  
  
  pub unsafe fn defer_destroy<T>(&self, ptr: Shared<T>)
然后是我們將看到三大指針類型:

Shared

我們剛剛在  defer_destroy  的函數簽名中看到了  Shared<T>  ,這是一個被Guard的生命周期  'g  所保護的指針類型,相當于  &'g T  。它保證了Guard存在期間數據的可訪問。

Owned

這相當于  Box<T>  ,是一個不會被其他線程接觸到的量。

Atomic

這是一個可以在線程間交換的原子指針。可以在  Guard  的保護下從中讀出  Shared<T>
    
  
  
  pub fn load(&self, ord: Ordering, &'g Guard) -> Shared<'g, T>
也可以將  Owned<T>  或者  Shared<T>  (即  Pointer<T>  )存入
    
  
  
  pub fn store<P>(&self, new: P, ord: Ordering)where    P: Pointer<T>,
也可以對其進行CAS操作
    
  
  
  pub fn compare_and_set<O, P>(    &self,    current: Shared<T>,    new: P,    ord: O,    &'g Guard) -> Result<Shared<'g, T>, CompareAndSetError<'g, T, P>>where    O: CompareAndSetOrdering,    P: Pointer<T>,

實現并發棧

有了這些API,我們就可以實現一個無鎖的MPMC的Treiber棧了。
    
  
  
  
use std::mem::ManuallyDrop;use std::ptr;use std::sync::atomic::Ordering::{Acquire, Relaxed, Release};
use crossbeam_epoch::{self as epoch, Atomic, Owned};
#[derive(Debug)]pub struct TreiberStack<T> {    head: Atomic<Node<T>>,}
#[derive(Debug)]struct Node<T> {    data: ManuallyDrop<T>, // 告訴編譯器該變量不需要自動Drop    next: Atomic<Node<T>>,}
impl<T> TreiberStack<T> {    pub fn new() -> TreiberStack<T> {        TreiberStack {            head: Atomic::null(),        }    }
   pub fn push(&self, t: T) {        let mut n = Owned::new(Node {            data: ManuallyDrop::new(t),            next: Atomic::null(),        });
       let guard = epoch::pin(); // 標記當前線程為活躍
       loop {            let head = self.head.load(Relaxed, &guard);            n.next.store(head, Relaxed);
           match self.head.compare_and_set(head, n, Release, &guard) { // CAS                Ok(_) => break,                Err(e) => n = e.new,            }        }    }
   pub fn pop(&self) -> Option<T> {        let guard = epoch::pin(); // 標記當前線程為活躍        loop {            let head = self.head.load(Acquire, &guard);
           match unsafe { head.as_ref() } {                Some(h) => {                    let next = h.next.load(Relaxed, &guard);
                   if self                        .head                        .compare_and_set(head, next, Relaxed, &guard) // CAS                        .is_ok()                    {                        unsafe {                            guard.defer_destroy(head); // 將垃圾加入列表                            return Some(ManuallyDrop::into_inner(ptr::read(&(*h).data))); // 返回節點中的數據                        }                    }                }                None => return None,            }        }    }
   pub fn is_empty(&self) -> bool {        let guard = epoch::pin();        self.head.load(Acquire, &guard).is_null()    }}
impl<T> Drop for TreiberStack<T> {    fn drop(&mut self) {        while self.pop().is_some() {}    }}
   
     

關于crossbeam-epoch中基于epoch的無鎖垃圾收集原理是什么就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

江陵县| 长乐市| 两当县| 芦溪县| 宜都市| 吴桥县| 调兵山市| 景泰县| 阳新县| 桦川县| 邢台县| 南木林县| 新丰县| 黔东| 保康县| 新津县| 麻城市| 新晃| 海安县| 合作市| 竹北市| 竹山县| 大新县| 木里| 泾阳县| 松潘县| 广河县| 临夏县| 嵩明县| 兴宁市| 德保县| 龙海市| 五莲县| 义乌市| 多伦县| 会理县| 桦甸市| 武宣县| 青龙| 南丰县| 大名县|