fork源码概要分析

2023-05-16

fork属于系统调用,首先从用户态切换到内核态,这个过程前面已经说过了,到了内核态之后就是调用sys_fork(),然后调用do_fork():

asmlinkage int sys_fork(struct pt_regs regs)
{
	return do_fork(SIGCHLD, regs.esp, &regs, 0, NULL, NULL);
}

这个过程会传递一些信号值和寄存器进去。


do_fork功能概要:

1、为子进程分配pid,

2、调用copy_process()函数进行一系列的copy

3、将子进程加入进程调度队列,等待cpu的调度

copy_process()功能概要:

1、为子进程申请一个PCB(task_struct)

调用dup_task_struct()函数,一般分配8k的物理页面,1k用于保存task_struct(PCB),另外一部分用作子进程的内核堆栈

	p = dup_task_struct(current);
	if (!p)
		goto fork_out;


2、对PCB进行初始化,如自旋锁,定时器

	INIT_LIST_HEAD(&p->children);
	INIT_LIST_HEAD(&p->sibling);
	p->vfork_done = NULL;
	spin_lock_init(&p->alloc_lock);
	spin_lock_init(&p->proc_lock);

	clear_tsk_thread_flag(p, TIF_SIGPENDING);
	init_sigpending(&p->pending);


3、将父进程的拷贝内存管理mm_struct,文件描述符files,文件系统fs,信号,信号处理函数

if ((retval = copy_semundo(clone_flags, p)))
		goto bad_fork_cleanup_audit;
	if ((retval = copy_files(clone_flags, p)))
		goto bad_fork_cleanup_semundo;
	if ((retval = copy_fs(clone_flags, p)))
		goto bad_fork_cleanup_files;
	if ((retval = copy_sighand(clone_flags, p)))
		goto bad_fork_cleanup_fs;
	if ((retval = copy_signal(clone_flags, p)))
		goto bad_fork_cleanup_sighand;
	if ((retval = copy_mm(clone_flags, p)))
		goto bad_fork_cleanup_signal;
	if ((retval = copy_keys(clone_flags, p)))
		goto bad_fork_cleanup_mm;
	if ((retval = copy_namespace(clone_flags, p)))
		goto bad_fork_cleanup_keys;

这里还对寄存器的值进行了copy和初始化,把eax的值设为0(所以子进程返回值为0),并设置EIP为ret_from_fork的起始地址(子进程从此处开始执行)

retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
	if (retval)
		goto bad_fork_cleanup_namespace;


4、调用sched_fork()对子进程的静态优先级初始化,并设置子进程为TASK_RINNING状态

sched_fork(p);



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

fork源码概要分析 的相关文章

  • 这是关闭 fork 上的套接字描述符的正确方法吗?

    考虑这段代码 socket fd start server port while 1 new socket fd accept client socket fd int pid fork if pid 0 I am the child se
  • 正确的 chromium 浏览器品牌?

    我正在研究 Chromium 叉子 如何替换 Chromium 资源和应用程序包 资源 我发现有一天android branding res dirsgn 参数是介绍 https chromium googlesource com chro
  • 更新 Github 上分叉存储库的多个分支

    我有一个分叉的 github 存储库 称为 repo O 称为我的分叉 repo F 其中包含大约 8 个分支 其他贡献者已在 repo O 的多个分支上对 repo O 进行了多次 100 次 提交 我现在想将这些更改放入我的分叉存储库
  • GCC 声明: typedef __pid_t pid_t?

    我对 例如 pid t 的声明感到困惑 pid t 是什么意思 它是其他地方定义的另一种类型吗 如果是 在哪里 为什么我的 types h 在 ubuntu 13 04 64 位中定义 pid t 如下 ifndef pid t defin
  • Errno::ENOMEM:无法分配内存 - cat

    我有一项在生产环境中运行的作业 用于处理 xml 文件 xml 文件总共约为 4k 大小为 8 到 9 GB 处理后我们得到 CSV 文件作为输出 我有一个 cat 命令 它将所有 CSV 文件合并到我得到的单个文件中 Errno ENOM
  • 使用 printf 在 c 中 fork() [重复]

    这个问题在这里已经有答案了 有 2 个不同的程序 它们都很小 例如 int main printf print hello fork int main printf print hello n fork 输出 1 是 print hello
  • 为什么fork后关闭文件描述符会影响子进程?

    我想通过单击按钮在linux中运行程序 因此我编写了一个函数execute void execute const char program call const char param pid t child vfork if child 0
  • fork 后调试子进程(配置了 follow-fork-mode 子进程)

    我正在开发一个应用程序 父级分叉子级来处理某些任务 我遇到一个问题 我已将 gdb 配置为 follow fork mode 子级 但在 fork 后 到达断点后 它发送 SIGTRAP 但子级以某种方式终止并向父级发送 SIGCHLD 我
  • 为什么我的编译器不接受 fork(),尽管我包含了

    这是我的代码 只是为了测试 fork 而创建 include
  • fork() & 内存分配行为

    我在一个禁用交换和禁用内存过量使用的系统上工作 假设我的进程当前消耗 100 MB 内存 而系统可用内存小于 100 MB 如果我执行 fork 它会失败 因为内核也尝试为子进程分配 100 MB 的空间吗 我读过 Linux 在分叉时使用
  • Pipe、Fork 和 Exec - 父进程和子进程之间的双向通信

    我的操作系统类中的作业要求我通过在同一程序上递归调用 exec 来构建二进制进程树 目标是将某些任意任务拆分为单独的进程 父级应与子级通信 子级应仅通过无名管道与父级通信 这个想法是 父级向每个子级发送一半的工作 并且递归地继续 直到满足基
  • bash fork 炸弹的另一个版本是如何工作的?

    我大致了解如何这个通用版本 https stackoverflow com questions 991142 how does this bash fork bomb work bash fork 炸弹的工作原理 然而 我见过另一个版本 特
  • 分叉/多线程进程|重击

    我想让我的代码的一部分更加高效 我正在考虑让它分叉成多个进程 并让它们一次执行 50 100 次 而不是只执行一次 例如 伪 for line in file do foo foo2 foo3 done 我希望这个 for 循环运行多次 我
  • fork 和 exec 之间的区别

    两者有什么区别fork and exec 指某东西的用途fork and exec它体现了 UNIX 的精神 它提供了一种非常简单的方法来启动新进程 The fork调用基本上复制了当前进程 在almost任何方式 并非所有内容都会被复制
  • 子进程中的变量修改

    我正在研究科比和奥哈拉伦的作品Computer Systems A Programmer s Perspective 练习 8 16 要求程序的输出如下 我更改了它 因为他们使用了一个你可以在他们的网站上下载的头文件 include
  • 父进程和子进程如何进行信号量操作?

    semget 调用是否在父进程和子进程之间共享信号量 我有这段代码 对于相同的代码 我观察到如果父进程首先运行 子进程有时会获得更改后的信号量值 但是当子进程首先运行时 父进程似乎永远不会携带更改后的信号量 为什么会发生这种情况 谁能向我解
  • 无法在 github 上的特定分支上生成 git no such file or directory

    问题出在这个 fork repo 上 https github com RubenWillems CCNet https github com RubenWillems CCNet 我可以在同一台笔记本电脑上安装其他叉子 但不能使用此叉子
  • 从 exit() 和 fork() 返回的结果奇怪地发生了位移

    我有一个 C 代码 有时会自行分叉 每个分叉都会执行一些操作 然后返回一个错误代码 目前 每个子进程返回其 ID 0 n void other int numero exit numero int main for int i 0 i lt
  • while 循环中的 scanf

    在这段代码中 scanf只工作一次 我究竟做错了什么 include
  • Linux/POSIX:为什么 fork() 不分叉*所有*线程

    众所周知 POSIX下创建新进程的默认方式是使用fork 在 Linux 下 这在内部映射到clone 我想知道的是 众所周知 当一个人打电话时fork 子进程是用单个线程创建的 调用的线程fork cf https linux die n

随机推荐