gpt4 book ai didi

C++ - 使用局部变量和全局变量时的不同并发行为

转载 作者:搜寻专家 更新时间:2023-10-31 01:30:34 25 4
gpt4 key购买 nike

给定这个程序:

#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中挪用的.在当前状态下,它的行为完全符合预期,两个线程都以未指定的顺序将数字压入堆栈,然后以正确的顺序打印堆栈。无论我是否为线程指定默认的 lambda 捕获,它都有效。但是,当我将堆栈 x 的声明移到 main() 中时,程序在打印堆栈内容时会遇到段错误。 GDB 告诉我,当在最后的循环中访问 nod->data 时会发生这种情况,并且运行 info locals 会使 gdb 崩溃。到底是怎么回事?为什么它甚至有所作为?

最佳答案

我不确定,但是,您的代码 head 成员在哪里初始化?当您将对象创建为全局变量(在 main 函数之上)时,head 将具有 0 值,但是当您在 main 函数中将堆栈对象创建为局部变量时,head 将包含垃圾数据 - 随机值。

关于来自 cppreference.com 的默认构造函数

1) The default constructor is trivial: no initialization takes place other than zero initialization of static and thread-local objects. std::atomic_init may be used to complete initialization.

关于C++ - 使用局部变量和全局变量时的不同并发行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47649828/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com