在考虑共享内存的整个概念之后,出现了一个问题:
两个进程可以共享同一个共享内存段吗?两个线程可以共享相同的共享内存吗?
在更清楚地考虑之后,我几乎肯定两个进程可以共享相同的共享内存段,其中第一个是父亲,第二个是子,它是用{{1}创建的两个线程怎么样?
谢谢
答案 0 :(得分:19)
两个进程可以共享同一个共享内存段吗?
是和否。通常使用现代操作系统,当另一个进程从第一个进程forked开始时,它们共享相同的内存空间,并在所有页面上设置copy-on-write。对任何读写内存页面进行的任何更新都会导致对页面进行复制,因此将有两个副本,并且将不再在父进程和子进程之间共享内存页面。这意味着只会共享只读页面或未写入的页面。
如果某个进程的不已从另一个进程分叉,则它们通常不共享任何内存。一个例外是,如果您运行同一程序的两个实例,那么他们可以共享code and maybe even static data segments,但不会共享其他页面。
还有specific memory-map calls共享相同的内存段。该调用指定映射是只读还是读写。如何做到这一点非常依赖操作系统。
两个线程可以共享同一个共享内存吗?
当然可以。通常,多线程进程内的所有内存都由所有线程“共享”。这通常是线程的定义,因为它们都在同一个内存空间中运行。
线程还具有与处理器/核心相关的高速内存中cached memory segments的复杂性。此高速缓存的内存不共享,并且根据同步操作,内存页面的更新将刷新到中央存储中。
答案 1 :(得分:3)
通常,进程的一个主要方面是防止共享内存!通过共享内存段的进程间通信在最常见的操作系统上肯定是可能的,但默认情况下不存在这些机制。未能正确设置和管理共享区域可能会导致segFault / AV(如果您是幸运的话)和UB(如果不是)。
然而,属于同一进程的线程没有这样的硬件内存管理保护可以分享他们喜欢的任何东西,明显的缺点是他们几乎可以随心所欲地腐败。我从来没有真正发现这是一个很大的问题,尤其是现代的OO语言倾向于将指针“结构化”为对象实例(Java,C#,Delphi)。
答案 2 :(得分:2)
是的,两个进程都可以附加到共享内存段。如果不是这样,那么共享内存段就不会有多大用处,因为这是共享内存段背后的基本思想 - 这就是为什么它是几种形式的IPC(进程间通信)之一。
同一进程中的两个线程也可以连接到共享内存段,但鉴于它们已经共享了它们所属进程的整个地址空间,可能没什么意义(尽管有人可能会看到这对于提出一个或多或少有效的用例来说是一个挑战。)
答案 3 :(得分:1)
一般而言,每个进程占用与所有其他进程隔离的内存空间,以避免不必要的交互(包括那些代表安全问题的交互)。但是,通常存在用于共享存储器部分的进程的手段。有时这样做是为了减少RAM占用空间(VAX / VMS中的“已安装文件”就是这样一个例子)。它也可以是协作流程进行通信的一种非常有效的方式。如何实现/结构化/管理共享(例如父/子)取决于特定操作系统提供的功能和应用程序代码中实现的设计选择。
在一个进程中,每个线程都可以访问与同一进程的所有其他线程完全相同的内存空间。线程唯一独有的就是“执行上下文”,其中一部分是它的堆栈(尽管没有什么能阻止一个线程访问或操纵堆栈“属于”同一进程的另一个线程)。