{eval=Array;=+count(Array);}

问答专栏Q & A COLUMN

Linux的写时拷贝所指的“写入”,具体是指什么?

reclayreclay 回答0 收藏1
收藏问题

2条回答

mist14

mist14

回答于2022-06-28 10:13

linux的进程

Linux 内核在系统启动的最后阶段会启动 init 进程。Linux 系统的进程之间存在着明显的继承关系,所有的进程都是 pid 为 1 的 init 进程的后代。

其他一些操作系统在创建进程时,首先在地址空间里创建进程,读入可执行文件,最后开始执行。Linux 是类 Unix 的操作系统,关于进程创建,它不同于前面那些操作系统,而是定义了 fork() 和 exec() 两组函数。这里以 fork() 函数为例介绍题主所说的“写时拷贝”。

linux创建进程的资源

fork() 函数通过拷贝父进程创建子进程,子进程与父进程的区别仅仅在于 pid,ppid 和一些资源的统计量,比如挂起的信号等。在早期,fork() 函数会将父进程的所有其他资源都复制给子进程。这种设计过于简单粗暴,因为子进程也许并不需要父进程的资源,如果子进程被创建后,转而执行和之前毫不相关的工作,那之前拷贝资源的开销就浪费了,一点意义也没有。

为了解决上面提到的可能会出现浪费的问题,“写时拷贝”的概念就被提出了。写时拷贝是一种可以推迟甚至免去拷贝数据的技术。子进程被创建后,系统将父进程的资源以只读的方式共享给子进程,这样子进程能够使用原本应该拷贝给子进程的数据,而同时又不会“污染”父进程。

这样一来,如果子进程只需要读取父进程数据,或者不需要使用父进程的数据,那么拷贝就免去了。如果子进程需要写这部分数据,则为了保证进程之间的数据独立性,系统才会将父进程的资源拷贝给子进程。

实例

结合上面这两点,就是“写时拷贝”的含义了,下面给出 demo:

char *buf = (char*)malloc(100*1024*1024);
int pid = fork();
if(pid==0){
printf("child exit ");
free(buf);
exit(0);
}else{
wait(&status);
free(buf);
exit(0);
}

对于上面这种情况,因为子进程没有用到父进程的 buf,所以系统就免去了拷贝 buf 100MB 的开销,提升了效率。

char *buf = (char*)malloc(100*1024*1024);
int pid = fork();
if(pid==0){
buf[0] = 1;
printf("child exit ");
free(buf);
exit(0);
}else{
wait(&status);
free(buf);
exit(0);
}

而对于上面这种情况,因为子进程需要 buf,系统就不可避免的要把父进程的资源拷贝给子进程了。


这就是“写时拷贝”了。

评论0 赞同0
  •  加载中...
iamyoung001

iamyoung001

回答于2022-06-28 10:13

写入缓存

评论0 赞同0
  •  加载中...

相关问题

最新活动

您已邀请0人回答 查看邀请

我的邀请列表

  • 擅长该话题
  • 回答过该话题
  • 我关注的人
向帮助了您的网友说句感谢的话吧!
付费偷看金额在0.1-10元之间
<