本文介绍了C ++线程之间的内存共享的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新的线程在C + +,我试图得到一个清晰的图片,如何共享/不共享线程之间的内存。我使用 std :: thread 和C ++ 11。
根据我在其他SO问题上阅读的内容,堆栈内存仅由一个线程拥有,内存在线程之间共享。所以从我认为我理解堆栈与堆,以下应该是真的:

I'm new to threading in C++, and I'm trying to get a clear picture about how memory is shared/not shared between threads. I'm using std::thread with C++11.From what I've read on other SO questions, stack memory is owned by only one thread and heap memory is shared between threads. So from what I think I understand about the stack vs. the heap, the following should be true:

#include <thread>
using namespace std;

class Obj {
public:
    int x;
    Obj(){x = 0;}
};

int main() {
    Obj stackObj;
    Obj *heapObj = new Obj();
    thread t([&]{
        stackObj.x++;
        heapObj->x++;
    });
    t.join();
    assert(heapObj->x == 1);
    assert(stackObj.x == 0);
}

原谅我,如果我搞砸了一堆东西,lambda语法是非常新的对我来说。但希望我想要做的是一致的。
这将如我所料吗?如果不是,我误解了什么?

forgive me if I screwed up a bunch of stuff, lambda syntax is very new to me. But hopefully what I'm trying to do is coherent.Would this perform as I expect? And if not, what am I misunderstanding?

推荐答案

内存是内存。 C ++中的对象占用内存中的一些位置;该位置可以在堆栈上或堆上,或者它可能已被静态分配。无论对象位于何处:具有引用或指向该对象的指针的任何线程都可以访问该对象。如果两个线程有​​一个引用或指向该对象的指针,那么这两个线程都可以访问它。

Memory is memory. An object in C++ occupies some location in memory; that location may be on a stack or on the heap, or it may have been statically allocated. It doesn't matter where the object is located: any thread that has a reference or pointer to the object may access the object. If two threads have a reference or a pointer to the object, then both threads may access it.

在程序中,创建一个工作线程c $ c> std :: thread ),它执行你提供的lambda表达式。因为你通过引用捕获 stackObj heapObj (使用 [& code> capture default),那个lambda对这两个对象都有引用。

In your program, you create a worker thread (by constructing a std::thread) that executes the lambda expression you provide it. Because you capture both stackObj and heapObj by reference (using the [&] capture default), that lambda has references to both of those objects.

这些对象都位于主线程的栈上(注意 heapObj 是一个指针类型的对象,它位于主线程的堆栈上,并指向一个动态分配的对象,它位于堆上)。没有这些对象的副本;而是,您的lambda表达式具有对对象的引用。它直接修改 stackObj ,并间接修改 heapObj 指向的对象。

Those objects are both located on the main thread's stack (note that heapObj is a pointer-type object that is located on the main thread's stack and points to a dynamically allocated object that is located on the heap). No copies of these objects are made; rather, your lambda expression has references to the objects. It modifies the stackObj directly and modifies the object pointed to by heapObj indirectly.

主线程加入工作线程后, heapObj-> x stackObj.x 1 的值。

After the main thread joins with the worker thread, both heapObj->x and stackObj.x have a value of 1.

使用值捕获默认值( [=] ),您的lambda表达式将 复制 stackObj heapObj 。在lambda表达式中的表达式 stackObj.x ++ 会增加 copy ,而 stackObj 您在 main()中声明的名称将保持不变。

If you had used the value capture default ([=]), your lambda expression would have copied both stackObj and heapObj. The expression stackObj.x++ in the lambda expression would increment the copy, and the stackObj that you declare in main() would be left unchanged.

如果您通过值捕获 heapObj ,则只复制指针本身, ,它仍然指向同一个动态分配的对象。表达式 heapObj-> x ++ 将取消引用该指针,产生通过创建的 Obj new Obj(),并增加其值。然后,您会在 main()结束时观察到 heapObj-> x 已递增。

If you capture the heapObj by value, only the pointer itself is copied, so while a copy of the pointer is used, it still points to the same dynamically allocated object. The expression heapObj->x++ would dereference that pointer, yielding the Obj you created via new Obj(), and increment its value. You would then observe at the end of main() that heapObj->x has been incremented.

(注意,为了修改通过value捕获的对象,lambda表达式必须声明为 mutable 。)

(Note that in order to modify an object captured by value, the lambda expression must be declared mutable.)

这篇关于C ++线程之间的内存共享的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-27 04:58
查看更多