大家来一起讨论一下系统调用fork() clone() vfork() 我开个头

xjgarchermind 2011-07-22 11:58:00
看内核代码介绍有关
fork()
clone()
vfork()
3个系统调用
看了看介绍
感觉还是没法能够真正理解其内涵
所以贴出来大家一起讨论一下!
...全文
158 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
xjgarchermind 2011-08-05
  • 打赏
  • 举报
回复
不结贴 这个课题就是用来讨论学习的 呵呵 大家对这3个系统函数有什么独到见解都可以发表一下啊
xjgarchermind 2011-08-05
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 bokutake 的回复:]
引用 11 楼 qiyu1988 的回复:

fork()运行后会把父进程的数据、堆栈等资源复制一份,很耗内存


不会的耗费内存和时间的,UNIX中就已经引入写时复制技术了。复制用户控件时只是简单的在内存页表上,做个重复的映射。新的进程的虚拟内存空间和原来的进程虚拟内存空间映射到同一个物理内存上。通过页写保护位,当时图写入内存页时,内核再分配新的物理内存来只复制那个要修改的页。
[/Quote]

领教了 你的意思是 fork的时候 不是马上进行内存数据复制? 而是等到要用到某些数据时 再另行拷贝? 但是父进程还在运行的话 如何保证数据的一致呢 因为拷贝时候的点数据场景 变了啊
LoveZhanHaiTao 2011-08-05
  • 打赏
  • 举报
回复
觉得你好像我一个朋友的,直觉告诉我的!呵呵!小意
辰岡墨竹 2011-08-05
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 qiyu1988 的回复:]

fork()运行后会把父进程的数据、堆栈等资源复制一份,很耗内存
[/Quote]

不会的耗费内存和时间的,UNIX中就已经引入写时复制技术了。复制用户控件时只是简单的在内存页表上,做个重复的映射。新的进程的虚拟内存空间和原来的进程虚拟内存空间映射到同一个物理内存上。通过页写保护位,当时图写入内存页时,内核再分配新的物理内存来只复制那个要修改的页。
wangzi851011 2011-08-02
  • 打赏
  • 举报
回复
我顶~!~~
qq495591230 2011-08-02
  • 打赏
  • 举报
回复
不会!!!!!!!!!!!!!!1
jiahehao 2011-08-02
  • 打赏
  • 举报
回复
楼主结帖率为0。。。。。。。
qiyu1988 2011-08-02
  • 打赏
  • 举报
回复
fork()运行后会把父进程的数据、堆栈等资源复制一份,很耗内存
翔云123456 2011-07-31
  • 打赏
  • 举报
回复
另外,fork vfork都是调用了clone
最后clone调用do_fork
翔云123456 2011-07-31
  • 打赏
  • 举报
回复
fork():创建时,飞父进程与子进程暂时共享代码和数据,只要有一个改变共享代码数据,就会各自得到一个拷贝

vfork():
父与子共享代码数据,创建子进程后,父进程要等待,直到子进程运行完毕,父进程才继续执行
昵称很不好取 2011-07-22
  • 打赏
  • 举报
回复
fork后的子进程共享父进程的代码
xjgarchermind 2011-07-22
  • 打赏
  • 举报
回复
首先我们贴一段应用代码来做分析
#include <stdio.h>
int main()
{
int child;
char *args[] = { "/bin/echo", "Hello", "World!", NULL};

if (!(child = fork()))
{
/* child */
printf("pid %d: %d is my father\n", getpid(), getppid());
execve("/bin/echo", args, NULL);
printf("pid %d: I am back, something is wrong!\n", getpid());
}
else
{
int myself = getpid();
printf("pid %d: %d is my son\n", myself, child);
wait4(child, NULL, 0, NULL);
printf("pid %d: done\n", myself);
}
return 0;
}

首先main函数肯定是父进程了
当调用fork后,返回时,子进程产生了
那么子进程从哪儿开始执行呢?
xjgarchermind 2011-07-22
  • 打赏
  • 举报
回复
实际上 我看了内核代码的进程介绍也是云里雾里

比如说fork,看这意思它只是复制了父进程的task_struct数据结构,如果没有自己的执行体,显然就没什么意义了 那么就只能共享父进程的执行体了 即fork返回后的地方开始执行

那么上面这段代码 父进程fork返回的地方是if (!(child = fork()))

子进程判断这个返回值

可为何又是等于0开始的
{
/* child */
printf("pid %d: %d is my father\n", getpid(), getppid());
execve("/bin/echo", args, NULL);
printf("pid %d: I am back, something is wrong!\n", getpid());
}

是自己的执行体呢?

这又怎么理解呢?

还有系统调用返回后回到用户空间 必然存在着进程调度

那么这个时候的CPU会去执行哪个进程呢?

父进程?

还是刚刚创建的子进程呢?
dongjiawei316 2011-07-22
  • 打赏
  • 举报
回复
clone()创建一个子进程,并可以指定进程开始运行的位置。实际上由于linux下并没有完全意义上的线程概念,如果clone创建的这个子进程和父进程共享内存空间的话,那么他就是linux下,我们通常认为的线程了。
name_110 2011-07-22
  • 打赏
  • 举报
回复
子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本,同时共享代码段。
所以,fork返回后他们都将执行接下来相同的代码
为了区分父进程和子进程,fork返回0表示子进程,fork返回非0表示父进程

那么子进程从哪儿开始执行呢? 子进程从fork()语句返回后就开始执行了

4,438

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧