無鎖資料結構三 無鎖資料結構的兩大問題

2021-08-21 01:14:28 字數 1966 閱讀 3243

struct tagged_ptr

tagged_ptr( t * p ): ptr(p), tag(0) {}

tagged_ptr( t * p, unsigned

int n ): ptr(p), tag(n){}

t * operator->() const };

標籤作為乙個版本號,隨著標籤指標上的每次cas運算增加,並且只增不減。一旦需要從容器中非物理地移除某個元素,就應將其放入乙個放置空閒元素的列表中。在空閒元素列表中,邏輯刪除的元素完全有可能被再次呼叫。因為是無鎖資料結構,乙個執行緒刪除x元素,另外乙個執行緒依然可以持有標籤指標的本地副本,並指向元素字段。因此需要乙個針對每種t型別的空閒元素列表。多數情況下,將元素放入空閒列表中,意味著呼叫這個t型別資料的析構函式是非法的(考慮到並行訪問,在析構函式運算的過程中,其它執行緒是可以讀到此元素的資料)。

template struct node  ;

template class msqueue

void enqueue( t const& value )

e11: } else

}} // end loop

// trying to relocate tail to the inserted element

e13: cas(&m_tail, tail, tagged_ptr(pnode, tail.tag+1));

}bool dequeue( t& dest )

// tail isn』t at the last element

// trying to move tail forward

d9: cas(&m_tail, tail, tagged_ptr(next.ptr, tail.tag+1>));

d10: } else

}} // end of loop

// deallocate the old dummy node

d14: m_freelist.add(head.ptr);

d15: return true; // the result is in dest

}

每個執行緒都將自己正在訪問其不希望被釋放的記憶體物件儲存在plist中,使用完取出。

當任何執行緒刪除記憶體物件,把物件放入dlist。

當dlist中元素數量達到閾值,掃瞄dlist和plist,真正釋放在dlist中有而所以plist中沒有的元素。

template t>

void queue::enqueue(const t &data)

next = t->next;

if (next)

if (__sync_bool_compare_and_swap(&t->next, null, node))

} __sync_bool_compare_and_swap(&tail_, t, node);

}template t>

bool queue::dequeue(t &data)

t = tail_;

next.acquire(&h->next);

asm volatile("" ::: "memory");

if (head_ != h)

if (!next)

if (h == t)

data = next->data;

if (__sync_bool_compare_and_swap(&head_, h, next))

} /* h->next = (qnode *)1; // bad address, it's a trap! */

/* delete h; */

hazard_mgr_.retirenode(h);

return true;

}

風險指標(hazard pointers)——用於無鎖物件的安全記憶體**機制

再論 無鎖資料結構(下)

上回說到實現了乙個無鎖的 wrrm 的指標保護演算法,但存在乙個問題是 寫執行緒在更新指標之後,更新游離物件引用計數之前,被強制殺死,會造成讀取執行緒的活鎖,這有悖乙個原則 好像叫什麼 寫無關原則 即使乙個執行緒崩潰也不該對其他執行緒造成太大影響 當然,所有執行緒全部被殺的話,啥演算法都玩完 下面的...

基於鎖的併發資料結構

可以使用細粒度的鎖來減小佇列的臨界區,這裡使用了乙個dummy node用來進一步減小鎖的臨界區。若要判斷佇列是否為空,只需要執行下述判斷 head.get get tail 請注意,因為在進行push的時候需要修改tail,所以對tail的訪問和修改都需要進行加鎖。這裡使用get tail來封裝這...

資料結構無頭單鏈表

template class slist node t data node head node tail int size public slist 複製建構函式 slist const slist sl slist 尾插 void slistpushback t data 尾刪 void slis...