を使用して:C++ - 異なる同時behaviousこのプログラムを考えると地元の人やグローバル
#include <thread>
#include <iostream>
#include <atomic>
template<typename T>
struct node
{
T data;
node* next;
node(const T& data) : data(data), next(nullptr) {}
};
template<typename T>
class stack {
std::atomic<node<T>*> head;
public:
void push(const T& data) {
node<T>* new_node = new node<T>(data);
new_node->next = head.load();
while(!head.compare_exchange_weak(new_node->next, new_node));
}
node<T>* get_head() {
return head;
}
};
stack<int> x;
int main() {
std::cout << "main() starts" << std::endl;
const int MAKS_OP = 100;
std::thread t1{[&]{
for (int i = 0; i < MAKS_OP; ++i) {
x.push(i);
std::string s = "Thread 1 added ";
s += std::to_string(i);
s += " to the stack!\n";
std::cout << s;
}
}};
std::thread t2{[&]{
for (int i = 0; i < MAKS_OP; ++i) {
x.push(i);
std::string s = "Thread 2 added ";
s += std::to_string(i);
s += " to the stack!\n";
std::cout << s;
}
}};
t1.join();
t2.join();
for (auto nod = x.get_head(); nod != nullptr; nod = nod->next) {
std::cout << nod->data << "\n";
}
std::cout << "main() completes\n";
}
コードは、多かれ少なかれhereから充当されます。 現在の状態では、期待どおりに動作し、両方のスレッドが数値を指定しない順にスタックにプッシュし、スタックを正しい順序で印刷します。スレッドのデフォルトラムダキャプチャを指定するかどうかに関係なく動作します。しかし、スタックxの宣言をmain()に移動すると、プログラムはスタックの内容を出力するときにsegfaultに実行されます。 GDBは、最後にループのnod->data
にアクセスし、info locals
を実行するとgdbがクラッシュすることが起こっていると言います。何が起こっている?なぜそれは違いを生みますか?
バグが私は無駄にしているcppreferenceのhttp://en.cppreference.com/w/cpp/atomic/atomic/compare_exchange でもあります初期化されていないアトミックをデバッグするのに時間がかかっていて、コンパイラがそれについて警告していないことがあります。 cppcheckもそれを検出しませんでした。 – lars