multithreading 两个或多个线程如何在它们分配的堆上共享内存?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11909248/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 01:19:53  来源:igfitidea点击:

How do two or more threads share memory on the heap that they have allocated?

multithreadingheap

提问by Lemma Prism

As the title says, how do two or more threads share memory on the heap that they have allocated? I've been thinking about it and I can't figure out how they can do it. Here is my understanding of the process, presumably I am wrong somewhere.

正如标题所说,两个或多个线程如何在它们分配的堆上共享内存?我一直在想,但我不知道他们是怎么做到的。下面是我对这个过程的理解,想必我哪里错了。

Any thread can add or remove a given number of bytes on the heap by making a system call which returns a pointer to this data, presumably by writing to a register which the thread can then copy to the stack. So two threads A and B can allocate as much memory as they want. But I don't see how thread A could know where the memory that thread B has allocated is located. Nor do I know how either thread could know where the other thread's stack is located. Multi-threaded programs share the heap and, I believe, can access one another's stack but I can't figure out how.

任何线程都可以通过进行系统调用来在堆上添加或删除给定数量的字节,该调用返回指向该数据的指针,大概是通过写入一个寄存器,然后该线程可以将其复制到堆栈中。所以两个线程 A 和 B 可以根据需要分配尽可能多的内存。但是我看不到线程 A 如何知道线程 B 分配的内存位于何处。我也不知道任何一个线程如何知道另一个线程的堆栈所在的位置。多线程程序共享堆,我相信可以访问彼此的堆栈,但我不知道如何访问。

I tried searching for this question but only found language specific versions that abstract away the details.

我尝试搜索这个问题,但只找到了抽象出细节的语言特定版本。

Edit: I am trying not to be language or OS specific but I am using Linux and am looking at it from a low level perspective, assembly I guess.

编辑:我试图不针对特定语言或操作系统,但我使用的是 Linux 并且我想从低级的角度来看它,我猜是程序集。

采纳答案by usr

My interpretation of your question: How can thread A get to know a pointer to the memory B is using? How can they exchange data?

我对您问题的解释:线程 A 如何知道指向 B 正在使用的内存的指针?他们如何交换数据?

Answer: They usually start with a common pointer to a common memory area. That allows them to exchange other data including pointers to other data with each other.

答:它们通常以指向公共内存区域的公共指针开头。这允许它们相互交换其他数据,包括指向其他​​数据的指针。

Example:

例子:

  1. Main thread allocates some shared memory and stores its location in p
  2. Main thread starts two worker threads, passing the pointer pto them
  3. The workers can now use pand work on the data pointed to by p
  1. 主线程分配一些共享内存并将其位置存储在 p
  2. 主线程启动两个工作线程,将指针传递p给它们
  3. 工作人员现在可以使用p和处理指向的数据p

And in a real language (C#) it looks like this:

在真正的语言 (C#) 中,它看起来像这样:

//start function ThreadProc and pass someData to it
new Thread(ThreadProc).Start(someData)

Threads usually do not access each others stack. Everything starts from one pointer passed to the thread procedure.

线程通常不访问彼此的堆栈。一切都从传递给线程过程的一个指针开始。



Creating a thread is an OS function. It works like this:

创建线程是一个操作系统功能。它是这样工作的:

  1. The application calls the OS using the standard ABI/API
  2. The OS allocates stack memory and internal data structures
  3. The OS "forges" the first stack frame: It sets the instruction pointer to ThreadProc and "pushes" someData onto the stack. I say "forge" because this first stack frame does not arise naturally but is created by the OS artificially.
  4. The OS schedules the thread. ThreadProc does not know it has been setup on a fresh stack. All it knows is that someData is at the usual stack position where it would expect it.
  1. 应用程序使用标准 ABI/API 调用操作系统
  2. 操作系统分配堆栈内存和内部数据结构
  3. 操作系统“伪造”第一个堆栈帧:它将指令指针设置为 ThreadProc 并将 someData“推入”堆栈。我说“伪造”是因为第一个堆栈帧不是自然出现的,而是由操作系统人为创建的。
  4. 操作系统调度线程。ThreadProc 不知道它已在新堆栈上设置。它只知道 someData 位于它期望的通常堆栈位置。

And that is how someData arrives in ThreadProc. This is the way the first, initial data item is shared. Steps 1-3 are executed synchronously by the parent thread. 4 happens on the child thread.

这就是 someData 到达 ThreadProc 的方式。这是共享第一个初始数据项的方式。步骤 1-3 由父线程同步执行。4 发生在子线程上。

回答by Cratylus

A really short answer from a bird's view (1000 miles above):
Threads are execution paths of the same process, and the heap actually belongs to the process (and as a result shared by the threads). Each threads just needs its own stack to function as a separate unit of work.

鸟瞰(1000 英里以上)的一个非常简短的答案:
线程是同一进程的执行路径,而堆实际上属于该进程(因此由线程共享)。每个线程只需要自己的堆栈作为单独的工作单元运行。

回答by Peter Ritchie

Threads can share memory on a heap if they both use the same heap. By default most languages/frameworks have a single default heap that code can use to allocate memory from the heap. In unmanaged languages you generally make explicit calls to allocate heap memory. In C, that might be malloc, etc. for example. In managed languages heap allocation is usually automatic and how allocation is done depends on the language--usually through the use of the newoperator. but, that depends slightly on context. If you provide the OS or language context you're asking about, I might be able to provide more detail.

如果线程都使用相同的堆,则它们可以共享堆上的内存。默认情况下,大多数语言/框架都有一个默认堆,代码可以使用该堆从堆中分配内存。在非托管语言中,您通常会显式调用以分配堆内存。例如,在 C 中,这可能是malloc等。在托管语言中,堆分配通常是自动的,分配的方式取决于语言——通常是通过使用new运算符。但是,这稍微取决于上下文。如果您提供所询问的操作系统或语言上下文,我可能会提供更多详细信息。

回答by Saurabh Juneja

A Thread shared with other threads belonging to the same process: its code section, data section and other operating system resources such as open files and signals.

与属于同一进程的其他线程共享的线程:其代码段、数据段和其他操作系统资源,例如打开的文件和信号。