微软研究人员发表论文称用于创建进程的 fork 系统调用方式已经很落后,并且对操作系统的研究与发展产生了极大的负面影响,需要淘汰,作者同时提出了替代方案。

相信每位开发者都对操作系统中的 fork () 有一定的了解,至少知道它是用来创建进程的。fork 系统调用方式在 20 世纪 70 年代被创造出来,它通常与 exec () 组合使用,非常简单却很强大,被认为是一种天才式的设计、Unix 的伟大思想,至今 50 余年一直作为 POSIX 操作系统的原语存在,同时几乎每个 Unix shell、主要 Web 和数据库服务器、Google Chrome、Redis 甚至 Node.js 都使用 fork。

  然而微软系统研究实验室 Redmond 的研究人员 3 月份却发表了一篇论文,表示 fork 作为操作系统原语继续存在,阻碍了对操作系统的研究,“它是来自另一个时代的遗物,不适合现代系统,并且会带来一系列负面影响”,研究人员认为是时候将 fork 淘汰了。

  fork 简单已成神话

  论文中承认了 fork API 的优点,包括简单与缓解并发性,也肯定了 fork 在历史上的重要贡献,但更多地是列出了它在现代操作系统研究与发展中的弊端。

  研究人员认为 fork 本身就存在许多问题,另一方面,fork 在操作系统的研究与发展上也起了限制作用,论文指出有明确的证据表明支持 fork 限制了 OS 体系结构的变化,并限制了操作系统适应硬件演进的能力。

  乍一看可能会觉得 fork 很简单,而这也是它的一大特征,但是实际上,“这是一个具有欺骗性的神话”。

  fork 的语义已经影响了每个创建进程状态的新 API 的设计,POSIX 规范现在列出了关于如何将父状态复制到子进度的 25 个特殊情况,包括文件锁定、定时器、异步 IO 操作与跟踪等。此外,许多系统调用标志控制 fork 关于内存映射(Linux madvise () 标记 MADV_DONTFORK/DOFORK/WIPEONFORK 等)、文件描述符(O_CLOEXEC、FD_CLOEXEC)和线程(pthread_atfork ())的行为。任何重要的操作系统工具都必须通过 fork 记录其行为,并且用户模式库必须做好准备,以便随时 fork 它们的状态。fork 已经不再简单。

  fork 不是线程安全的,Unix 进程支持线程,但 fork 创建的子进程只有一个线程(调用线程的副本),当一个线程在 fork 时,如果另一个线程此时进行内存分配并持有堆锁,任何在子进程中分配内存的尝试(从而获得相同的锁)都将立即发生死锁。

  fork 很慢,fork 的性能一直是个问题,此前使用写时复制技术使其性能可接受,但是在今天,建立写时复制映射本身都成了一个性能问题,比如 Chrome 在 fork 时会经历了长达 100 毫秒的延迟,Node.js 应用在 exec 之前 fork 时,可以被阻塞几秒钟。fork+exec 与 spawn 的性能对比情况可以通过本文开头的图片直观看到。

  fork 无法扩展,系统规模的设计首先要避免不必要的共享,但 fork 进程会与其父进程共享所有内容,由于 fork 复制了进程操作系统状态的各个方面,这样复制与引用计数成本会比较低,所以 fork 其实是趋向于将状态集中在单片内核中,这就使得难以实现一些新技术,比如用于安全性和可靠性的内核划分。

  fork 与异构硬件不兼容,它将进程的抽象与包含它的硬件地址空间混为一谈。fork 将进程的定义限制为单个地址空间,并且是在某个核心上运行的单个线程。但现代硬件和在其上运行的程序并不是这样,硬件异构化越来越严重,使用有内核旁路 NIC 的 DPDK 或带有 GPU 的 OpenCL 的进程无法安全地 fork,因为操作系统无法复制 NIC/GPU 上的进程状态。这个问题至少已经困扰了 GPU 程序员十年,而随着未来的芯片上系统包含越来越多的状态加速器,情况只会变得更糟。

  “GET THE FORK OUT OF MY OS!”

  论文提出了替代 fork 的方案:包括一个高级 Spawn API 和一个低级类微内核 API 的组合。涉及到 posix_spawn ()、vfork ()、跨进程操作、clone ()、改进写时复制内存等内容。

  fork 的问题越来越严重,作者最后总结出必须做三件事来纠正这种情况,不仅要弃用 fork,还要改善替代方案,同时纠正我们关于 fork 的教学内容,不能再错误地宣扬 fork 的能力与设计水平。

本文转自:https://www.linuxprobe.com/system-call-mode.html

fork系统调用方式成为负担,需要淘汰的更多相关文章

  1. fork系统调用(转载)

    (1) fork系统调用说明 fork系统调用用于从已存在进程中创建一个新进程,新进程称为子进程,而原进程称为父进程.fork调用一次,返回两次,这两个返回分别带回它们各自的返回值,其中在父进程中的返 ...

  2. fork 系统调用

    对自己知识储备的感觉就是过于肤浅,很多东西知其名后就不了了之 此系列博客将记录进程分析的学习过程,希望能够多些深度 提到进程,最容易的想到就是fork系统调用,比较好和快速的找到的fork的相关信息就 ...

  3. 用 set follow-fork-mode child即可。这是一个 gdb 命令,其目的是告诉 gdb 在目标应用调用fork之后接着调试子进程而不是父进程,因为在 Linux 中fork系统调用成功会返回两次,一次在父进程,一次在子进程

    GDB的那些奇淫技巧 evilpan 收录于 Security  2020-09-13  约 5433 字   预计阅读 11 分钟  709 次阅读  gdb也用了好几年了,虽然称不上骨灰级玩家,但 ...

  4. 系统调用方式文件编程,王明学learn

    系统调用方式文件编程 一.文件描述符 在Linux系统中,所有打开的文件也对应一个数字,这个数字由系统来分配,我们称之为:文件描述符. 二.函数学习 2.1打开文件  open 2.1.2 函数原形 ...

  5. linux应用程序开发-文件编程-系统调用方式

    在看韦东山视频linux驱动方面有一些吃力,究其原因,虽然接触过linux应用程序编程,但是没有深入去理解,相关函数用法不清楚,正好看到国嵌视频对这一方面讲的比较透彻, 所以把学习过程记录下来,也作为 ...

  6. 一个fork()系统调用的问题

    转载:http://coolshell.cn/articles/7965.html 题目:请问下面的程序一共输出多少个“-”? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...

  7. 《Linux内核分析》 week6作业-Linux内核fork()系统调用的创建过程

    一.进程控制块PCB-stack_struct 进程在操作系统中都有一个结构,用于表示这个进程.这就是进程控制块(PCB),在Linux中具体实现是task_struct数据结构,它主要记录了以下信息 ...

  8. 以python代码解释fork系统调用

    import os print('Process (%s) start...' % os.getpid()) # Only works on Unix/Linux/Mac: pid = os.fork ...

  9. fork()系统调用的理解

    系统调用fork()用于创建一个新进程.我们可以通过下面的代码来理解,最好是能自己敲一遍运行验证. ​#include<stdio.h> #include<stdlib.h> ...

随机推荐

  1. 布局文件中fill_parent和match_parent有什么区别?

    1)fill_parent设置一个构件的布局为fill_parent将强制性地使构件扩展,以填充布局单元内尽可能多的空间.这跟Windows控件的dockstyle属性大体一致.设置一个顶部布局或控件 ...

  2. AOP五种执行时机

    动态代理四种增强方式 先创建一个service类 package com.zzj.calculatar.service; import org.springframework.stereotype.S ...

  3. sklearn中的多项式回归算法

    sklearn中的多项式回归算法 1.多项式回归法多项式回归的思路和线性回归的思路以及优化算法是一致的,它是在线性回归的基础上在原来的数据集维度特征上增加一些另外的多项式特征,使得原始数据集的维度增加 ...

  4. 网络OSI七层模型及各层作用 与 TCP/IP

    背景 虽然说以前学习计算机网络的时候,学过了,但为了更好地学习一些物联网协议(MQTT.CoAP.LWM2M.OPC),需要重新复习一下. OSI七层模型 七层模型,亦称OSI(Open System ...

  5. Typora: Markdown Reference (Typora下Markdown语法使用说明)

    引言 由于一直在使用Typora,这个是我使用过的最棒的Markdown编辑器,但是总是忽略某一个功能,于是决定认真看一下其帮助文档 这里做一个简单主要功能的中文翻译(按键对应Windows下). 标 ...

  6. 如果shell到win上出现乱码怎么办

    如果shell到win上出现这样的乱码怎么办? 如果出现了乱码,不慌一条命令搞定它!!! chcp 65001

  7. firewalld学习--service的使用和配置

    service配置文件 firewalld默认给我们提供的ftp的service配置文件ftp.xml <?xml version="1.0" encoding=" ...

  8. MAC 终端编辑完成后如何保存:

    如果是vi,则:Esc 退出编辑模式,输入以下命令: :wq 保存后退出vi,若为 :wq! 则为强制储存后退出(常用):w 保存但不退出(常用):w! 若文件属性为『只读』时,强制写入该档案:q 离 ...

  9. 部署 Helm【转】

    本节我们将安装和部署 Helm 客户端和 Tiller 服务器. Helm 客户端 通常,我们将 Helm 客户端安装在能够执行 kubectl 命令的节点上,只需要下面一条命令: curl http ...

  10. 51nod 1163:最高的奖励 优先队列

    1163 最高的奖励 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题  收藏  关注 有N个任务,每个任务有一个最晚结束时间以及一个对应的奖励.在结束时间之前完成该 ...