我想解釋只有1個問題,它顯示了這種方法的基本漏洞。
假設您目前僅支持插入操作而不支持其他任何操作。以下可能是插入操作的實現:
//Using C
BSTNode* insert(BSTNode* root,int value)
{
1 if(root == NULL){
2 return createNewNode(value);
3 }
4
5 if(root->data == value){
6 return root;
7 }
8 else if(root->data > value){
9 while(root->leftLock);
10 if(!root->left){
11 root->leftLock = true;
12 root->left = insert(root->left,value);
13 root->leftLock = false;
14 }
15 else{
16 root->left = insert(root->left,value);
17 }
18 }
19 else{
20 while(root->rightLock);
21 if(!root->right){
22 root->rightLock = true;
23 root->right = insert(root->right,value);
24 root->rightLock = false;
25 }
26 else{
27 root->right = insert(root->right,value);
28 }
29 }
30
31 return root;
32
}
在這種方法中,因爲只有最後一個節點(葉節點)的孩子會在插入值得到更新,所以我們沒有做任何鎖定,同時更新父母(當反覆回來時)。
我正在避免插入請求排隊和使用自旋鎖只是爲了保持它有點簡單。但是我將要加薪都是一樣的那種情況下的點...
考慮這個BST:
假設2個線程T1和T2調用試圖同時分別插入值25和26並且當前處於值爲20的BSTNode。 (最右邊的節點)。
現在讓與螺紋之間的上下文切換執行上面的代碼:
a. t1:
1. if(root == NULL) //not true, will go to line 5.
//switch
b. t2:
1. if(root == NULL) //not true, will go to line 5.
//switch
c. t1:
5. if(root->data == value){ //not true, will go to line 8.
8. else if(root->data > value) //not true, will go to line 19.
//switch
d. t2:
5. if(root->data == value){ //not true, will go to line 8.
//switch
e. t1:
19 else{
20 while(root->rightLock); // lock is not held by anyone, so continue.
21 if(!root->right){
//switch
f. t2:
8. else if(root->data > value) //not true, will go to line 19.
19 else{
20 while(root->rightLock); // lock is not helpd by anyone, so continue.
21 if(!root->right){
22 root->rightLock = true;
//switch
g. t1:
22 root->rightLock = true;
23 root->right = insert(root->right,value);
//switch
h. t2:
23 root->right = insert(root->right,value);
24 root->rightLock = false;
//switch
假設線23覆蓋該行的完全執行。
正如你可以在部分˚F,克和ħ兩個T1和T2正在進入臨界區不知道彼此的存在看到。代碼不應該允許這樣做。
那麼問題呢?
的問題是,有一段代碼,這本來是一個去要執行:
20 while(root->rightLock);
21 if(!root->right){
22 root->rightLock = true;
因此,我們可以通過使我們自己的不間斷指令,執行所有3個任務需要一些硬件控制如上所述。
據我所知,插入元素後樹會改變,但是它的新搜索可以從該特定節點本身開始,而不是從根開始。這將影響我們插入大量元素的時間。找到位置的任務只在路徑上的第一個節點被鎖定前才並行。要插入到根的不同側的值仍可以並行搜索。我並不期待p線程的性能是p倍,但它應該比順序更好。 – LearningToCode
@LearningToCode同意新搜索可以從該特定節點開始,同時它不能應用於相當數量的線程。所以唯一方便的解決方案將從一開始就開始,否則我們正在浪費時間轉換多個節點以繼續。您的第二點是有道理的。請花點時間分析它的影響。 :)) –