#include <iostream>
#include <atomic>
#include <memory>
template<typename T>
class LockFreeQueue {
public:
struct CountedNode;
private:
std::atomic<CountedNode> head;
public:
struct Node{
explicit Node(const T& d) : next(CountedNode()), data(std::make_shared<T>(d)), node_counter(0) { }
std::atomic<CountedNode> next;
std::shared_ptr<T> data;
std::atomic<unsigned> node_counter;
};
struct CountedNode {
CountedNode() noexcept : node(nullptr), counter(0) {}
explicit CountedNode(const T& data) noexcept : node(new Node(data) /* $4 */), counter(0) {}
Node* node;
int counter;
};
void push(const T& data)
{
CountedNode new_node(data), curr, incrementedNext, next /*($2) */;
CountedNode empty; /*($3) */
if (head.compare_exchange_strong(empty, new_node)) std::cout << "EQUALS\n"; // $1
else std::cout << "NOT EQUALS\n";
if (head.compare_exchange_strong(next, new_node)) std::cout << "EQUALS\n"; // $1
else std::cout << "NOT EQUALS\n";
}
};
int main() {
LockFreeQueue<int> Q;
Q.push(2);
return 0;
}
int main(){
LockFreeQueue<int> Q;
Q.push(2);
return 0;
}
好的。它編譯和執行沒有錯誤。但是,這仍然存在問題,我將在下面介紹。同一個班級的同一個實例,但行爲不同。可能的UB
http://coliru.stacked-crooked.com/a/1fe71fafc5dde518
在我的眼睛,導致它沒有預期: NOTEQUALS EQUALS
我有上面這段代碼野生問題。
特別是,行$1
的比較使我成爲一個問題。我的意思是,這個比較總是返回false,但它應該在第一次返回true。
我很困惑,所以我看着內存empty
和head
,實際上他們是不同的。 head
等於0x00000000 0x00000000 0x00000000 0x00000000
(當涉及字節),它似乎是確定的。但是empty
等於: 0x00000000 0x00000000 0x00000000 0x7f7f7f7f7f
。 $2
中next
更有趣的等於0x00000000 0x00000000 0x00000000 0x00000000
,所以實際上等於head
。但是,例如,curr
,incrementedNext
等於0x00000000 0x00000000 0x00000000 0x7f7f7f7f7f
。 所以這種行爲是不確定的,所以我想任何未定義的行爲,但爲什麼?我不正確的,請解釋我的這種行爲。
P.S.我知道在$4
內存泄漏,但現在我忽略它。
我編譯它爲: g++ -latomic main.cpp -std=c++14
。 我的gcc版本是6.1.0。我也在gcc 5.1.0上測試過。結果是一樣的。
鏈接到由@PeterCordes創建的源:https://godbolt.org/g/X02QV8
你[剛纔問這個(https://stackoverflow.com /問題/ 38862289 /的-相同情況下的最-同一類,但是,不同的行爲劣勢UB)。 –
是的,我刪除並創建了新的(正確的)帖子。 – Gilgamesz
@KerrekSB,這是一個問題嗎?畢竟,我刪除了我以前的。 – Gilgamesz