我想知道在对可变对象进行深度复制时,python解释器是否在写策略上应用了复制.
另外,我想知道深度复制是否也在不可变对象上执行(但这对我来说似乎很奇怪)
我一直在Linux上使用写时复制缓冲区,以下示例似乎按预期工作:
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define SIZE 4096
#define SHM_NAME "foobar"
int main(void)
{
int fd = shm_open(SHM_NAME, O_RDWR | O_CREAT, 0666);
int r = ftruncate(fd, SIZE);
char *buf1 = mmap(NULL, SIZE, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
strcpy(buf1, "Original buffer");
char *buf2 = mmap(NULL, SIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE, fd, 0);
// At this point buf2 is aliased to buf1
// Now modifying buf2 should trigger copy-on-write)... …Run Code Online (Sandbox Code Playgroud) 当尝试使用写时复制语义(PROT_READ | PROT_WRITE和MAP_PRIVATE)映射5GB文件时,会在2.6.26-2-amd64 Linux内核上发生这种情况.映射小于4GB的文件或仅使用PROT_READ工作正常.这不是本问题中报告的软资源限制问题 ; 虚拟限制大小是无限的.
这是重现问题的代码(实际代码是Boost.Interprocess的一部分).
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
main()
{
struct stat b;
void *base;
int fd = open("foo.bin", O_RDWR);
fstat(fd, &b);
base = mmap(0, b.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (base == MAP_FAILED) {
perror("mmap");
return 1;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
以下是发生的事情:
dd if=/dev/zero of=foo.bin bs=1M seek=5000 count=1
./test-mmap
mmap: Cannot allocate memory
Run Code Online (Sandbox Code Playgroud)
这是相关的strace(新编译的4.5.20)输出,如nos所述.
open("foo.bin", O_RDWR) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=5243928576, ...}) = 0
mmap(NULL, …Run Code Online (Sandbox Code Playgroud) 继续讨论这个问题后,我想知道如何使用本机C++以编程方式确定他们使用的std :: string实现是否利用了写时复制(COW)
我有以下功能:
#include <iostream>
#include <string>
bool stdstring_supports_cow()
{
//make sure the string is longer than the size of potential
//implementation of small-string.
std::string s1 = "012345678901234567890123456789"
"012345678901234567890123456789"
"012345678901234567890123456789"
"012345678901234567890123456789"
"012345678901234567890123456789";
std::string s2 = s1;
std::string s3 = s2;
bool result1 = (&s1[0]) == (&s2[0]);
bool result2 = (&s1[0]) == (&s3[0]);
s2[0] = 'X';
bool result3 = (&s1[0]) != (&s2[0]);
bool result4 = (&s1[0]) == (&s3[0]);
s3[0] = 'X';
bool result5 = (&s1[0]) != (&s3[0]); …Run Code Online (Sandbox Code Playgroud) 我的问题可能是一个措辞不好的问题,源于我对记忆管理的业余理解.
我担心的是:我有一个多次出现的Perl脚本.据我所知,在perldoc的fork页面中,正在实现copy-on-write.然后system(),每个孩子再次呼叫,呼叫外部程序.来自外部程序的数据被读回到子项中,并作为可存储文件转储,以便在所有子项退出后由父项处理并处理.
我担心的是我对这种情况的波动性.考虑一下,在我看来,最糟糕的情况:对于每个孩子,一旦新数据到达,整个写时复制内存就会被复制.如果是这种情况,我会在创建一些分支后快速遇到内存问题.
但另外,copy-on-write是否只复制包含所需数据的最小内存块?那么这个量子的记忆是什么?它的大小如何设定?
我不确定我所询问的细节是否依赖于语言或依赖于某些较低级别的过程.
之前copy on write (COW),当它表示父进程和子进程共享相同的地址空间时,这意味着它们共享相同的代码段,数据段,堆和堆栈吗?
如果父进程和子进程在COW之前共享相同的地址空间,那the page table entries are copied from parent process to child process意味着什么?
重复页表条目是否意味着重复地址空间?
以上(标题)是我主要关心的问题。而案例是
public class MyClass{
CopyOnWriteArrayList<Stuff> min;
...
public List<Stuff> get(){
return min;
}
}
Run Code Online (Sandbox Code Playgroud)
生成的列表是从get()负债中获得的吗?它会影响发生的事情min还是它自己的副本?例如,如果我迭代结果,get()会产生什么影响?
另外,当我们这样做的时候,相反怎么样?如果我做
List<Stuff> stuffs = new ArrayList<Stuff>();
addABunchOfItems(stuffs);
CopyOnWriteArrayList safeStuff = (CopyOnWriteArrayList) stuffs;
Run Code Online (Sandbox Code Playgroud)
关于并发支持,第三行及其之后safeStuff的状态是什么?stuffs
我有一个返回大型NumPy数组的类。这些数组被缓存在类中。我希望返回的数组是写时复制数组。如果调用者最终只是从数组中读取,则不会进行任何复制。这样可以避免使用多余的内存。但是,该数组是“可修改的”,但不会修改内部缓存的数组。
目前,我的解决方案是将所有缓存的数组设置为只读(a.flags.writeable = False)。这意味着,如果函数的调用者想要修改数组,则可能必须制作自己的数组副本。当然,如果源不是来自缓存,并且阵列已经可写,则它们将不必要地复制数据。
因此,最理想的情况是我喜欢这样的东西a.view(flag=copy_on_write)。似乎有个相反的标志,UPDATEIFCOPY一旦释放,副本就会更新原件。
谢谢!
我正在编写一些将备份数据组合到一个目录中的小脚本。然后目录内容将上传到云服务,然后我们可以将其删除。我想知道如何通过cp终端中的命令来利用 APFS 的写时复制功能。
Finder 做得很好。但是如果我运行cp Largefile LargeFileCopy它需要永远复制文件并相应地使用空间。
我搜索了很多资源,但没有发现任何具体的问题:
我知道在某些 linux 系统中,fork()系统调用与 copy-on-write 一起使用;也就是说,父子进程共享相同的地址空间,但是 PTE 现在被标记为read-only,以便稍后在 COW 中使用。当任何一个尝试访问一个页面时,PAGE_FAULT都会发生一个页面,并将该页面复制到另一个可以修改的地方。
但是,我无法理解操作系统如何到达共享 PTE 以将它们标记为“已读”。我假设当fork()系统调用发生时,操作系统在父页表上执行“页面遍历”并将它们标记为只读- 但我没有找到对此的确认,或有关该过程的任何信息。
有谁知道这些页面是如何被标记为只读的?将不胜感激任何帮助。谢谢!
copy-on-write ×10
linux-kernel ×3
fork ×2
macos ×2
mmap ×2
python ×2
algorithm ×1
apfs ×1
c ×1
c++ ×1
concurrency ×1
deep-copy ×1
java ×1
numpy ×1
page-tables ×1
perl ×1
process ×1
string ×1
terminal ×1