V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
bmpidev2019
V2EX  ›  分享创造

编程语言是如何实现并发的之操作系统篇

  •  
  •   bmpidev2019 ·
    madawei2699 · 2022-04-11 08:10:28 +08:00 · 5824 次点击
    这是一个创建于 717 天前的主题,其中的信息可能已经有所发展或是发生改变。

    从操作系统的视角介绍编程语言实现并发的底层概念,包括进程调度与 I/O 模型等。

    文章地址:编程语言是如何实现并发的之操作系统篇 · 构建我的被动收入

    这篇文章处于草稿状态,如果你对本文有任何建议或意见,请留言评论,感谢!

    第 1 条附言  ·  2022-04-29 08:58:16 +08:00
    文章已按大家的反馈更新成正式版,谢谢!
    25 条回复    2022-04-30 23:02:17 +08:00
    ligiggy
        1
    ligiggy  
       2022-04-11 08:57:12 +08:00
    图片上的是什么字体啊,挺好看的。
    clecho
        2
    clecho  
       2022-04-11 09:10:43 +08:00
    同问,确实看着挺舒服的
    gesse
        3
    gesse  
       2022-04-11 09:10:47 +08:00
    看着像仓耳今楷
    flowerains
        4
    flowerains  
       2022-04-11 09:11:04 +08:00
    写得不错,值得收藏
    bmpidev2019
        5
    bmpidev2019  
    OP
       2022-04-11 09:17:08 +08:00 via iPhone   ❤️ 1
    @ligiggy
    @clecho
    @gesse

    https://www.bmpi.dev/self/my-writing-story/250k/

    这篇文章里写着排版部分有介绍字体(霞鹜文楷)和排版的库
    iClass
        6
    iClass  
       2022-04-11 09:17:11 +08:00 via Android
    您是个战斗力超强的 Man 👨
    charlie21
        7
    charlie21  
       2022-04-11 09:25:17 +08:00
    计算机博大精深
    zhangleshiye
        8
    zhangleshiye  
       2022-04-11 10:04:49 +08:00
    这个网页图标有点意思.
    heijiaotuan123
        9
    heijiaotuan123  
       2022-04-11 11:29:40 +08:00
    老板,网站不能访问呀
    heijiaotuan123
        10
    heijiaotuan123  
       2022-04-11 11:30:11 +08:00
    🤣🤣 刚发完就可以访问了
    lxdlam
        11
    lxdlam  
       2022-04-11 11:49:57 +08:00   ❤️ 2
    仍然是有问题的哈。

    1. Go 的 Goroutine 在 1.14 之后就是基于信号抢占式调度的了( https://go.dev/doc/go1.14 ),因为没有手动的 yield ,并不是 cooperative 的。
    2. Java 的 Green Thread 已经在 1.3 之后被 Native Thread 取代,换句话说,现行的 JDK 的原生调度模型等同于 OS Thread 。Java 的新用户侧线程 Project Loom 会是新的 Green Thread 方案,但是仍然是抢占式调度的。
    3. 由于硬件和软件的进步,Windows 的 Fibers 已经日渐式微了( https://devblogs.microsoft.com/oldnewthing/20191011-00/?p=102989 ),在日常讨论中常用的 User-Thread 切换已经基本达到一样的性能。
    4. 抢占式调度和协作式调度的核心区别不是有新任务时是谁在执行,而是谁发出切换信号:抢占式调度往往在一些重要位置( sleep call ,timer tick )放置了中断信号,通过这个信号通知 scheduler 进行切换;协作式调度则是通过 thread 自己根据执行情况,主动交出控制权。
    lxdlam
        12
    lxdlam  
       2022-04-11 11:56:16 +08:00
    @lxdlam 好像记忆出现了偏差,Project Loom 应该是 cooperative 的。
    bmpidev2019
        13
    bmpidev2019  
    OP
       2022-04-11 13:01:21 +08:00 via iPhone   ❤️ 1
    @lxdlam

    1. 那 Go 这个和 Erlang 的有点相似了,那也不能放到协程分类里(这个我会修改)
    2. 这个文章里也是这个意思,green 这个概念是 Java1.1 提出,1.3 废弃,其实我很好奇为啥要废弃了
    3. Fibers 也是历史产物,现在已经看不到了
    4. 文章也是这个意思,可能我没表达清楚,可以修改下。

    感谢反馈👍
    lxdlam
        14
    lxdlam  
       2022-04-11 13:45:11 +08:00   ❤️ 1
    @bmpidev2019 废弃的原因其实是因为 Linux 的线程实现方式的历史原因。https://web.archive.org/web/20040211225937/http://java.sun.com/developer/technicalArticles/Programming/linux/

    注意到:
    > ... Each Linux thread is created as a process clone operation, which leaves the scheduling of threads to be a task of the process scheduler.

    而彼时的 Linux 内核版本离 2003 年真正实现了内核态的抢占调度( 2.6 版本,CFS 算法)还有 3 年,也就是说,这个时候的 Linux 只支持一个时间一个线程在跑,OS 无法主动抢占当前正在执行的线程,必须由用户侧程序来调用 schedule 。换句话说,这个时候创建的线程受到了 Linux Process Scheduler 的制约( Linux Scheduler 调度的最小单元是 Thread ),无法实现真正的并行(操作系统无法调度到其他 CPU 上),同时,这样实现的 Thread 切换跟 OS Thread 切换是一致的,也受到 OS Thread 切换的制约( Context Switch ,内核态-用户态进出)。

    > By comparison, on Solaris the Java threads are mapped onto user threads, which in turn are run on Lightweight processes (LWP). On Windows the threads are created inside the process itself. For this reason, creating a large number of Java threads on Solaris and Windows today is faster than on Linux. This means you might need to adjust programs that rely on platform-specific timing to take a little longer on startup when they run on Linux.

    正如你文章引用的 Solaris 调度系统图所说,Solaris 的调度存在 LWP 这个中间单元,这个中间单元其实类比于现在并发的 M:N 实现,实际是比较超前的。LWP 能被自由的调度到多个 Kernel Thread 上,多个 Kernel Thread 也可以被自由地调度到每个 CPU Core 上;而 Windows 的调度也是在 Process 的树形结构下调度的。在这两个系统下,由 JVM 实现的调度器能够自由地把 Task 进行低开销地切换(要么发生在 LWP 间,要么发生在 Process 内),系统调度的时候也不仅仅以 Thread 为单位( LWP-Kernel Thread 或者 Process-Thread ),使得在这两个平台上,Green Thread 的调度都是合理的。

    当然,随着后面 Linux 的崛起,Java 1.3 虽然放弃了 Green Thread 实现,但是 Project Loom 又把它带回来了,这也是 OpenJDK 认为的,Java 并发调用的未来。
    bmpidev2019
        15
    bmpidev2019  
    OP
       2022-04-11 13:53:48 +08:00 via iPhone
    @lxdlam 这么看 Erlang 的调度足够超前,Java 起了个大早却没能赶上好时候,导致多线程太重了。
    qW7bo2FbzbC0
        16
    qW7bo2FbzbC0  
       2022-04-11 15:41:13 +08:00
    问个文盲问题,一个不包含全局参数读写的函数,在被调用时会存在等待情况吗,类似于 A 调用完了,B 才会进行调用
    Sivan2017
        17
    Sivan2017  
       2022-04-11 23:07:44 +08:00
    网站是不是挂了?访问不了
    bmpidev2019
        18
    bmpidev2019  
    OP
       2022-04-12 03:21:08 +08:00 via iPhone
    @Sivan2017 要么你梯子问题,要么 vercel 在你区域不可用,网站是部署在 CDN 上,不存在挂的可能性
    liz2nku
        19
    liz2nku  
       2022-04-12 03:47:26 +08:00 via iPhone
    写得不错
    Sivan2017
        20
    Sivan2017  
       2022-04-12 12:56:33 +08:00
    @bmpidev2019 已经解决,是我这边网络出错了
    darksword21
        21
    darksword21  
       2022-04-29 09:37:18 +08:00 via iPhone
    rss 订上!
    tj3u2l
        22
    tj3u2l  
       2022-04-29 12:29:06 +08:00
    请教一下,文章开篇,那张系统监控界面的图片,是运行的什么命令?提前感谢🙏
    GeruzoniAnsasu
        23
    GeruzoniAnsasu  
       2022-04-29 13:30:40 +08:00
    操作系统篇,重点却不是操作系统?

    我还以为讲的是多核 CPU 如何管理线程和时间中断呢
    bmpidev2019
        24
    bmpidev2019  
    OP
       2022-04-29 21:38:09 +08:00 via iPhone
    @tj3u2l htop
    haah
        25
    haah  
       2022-04-30 23:02:17 +08:00
    操作系统通常不按教科书描述的那样清楚地定义与实现——操作系统概念(原书第 9 版)。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5456 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 08:51 · PVG 16:51 · LAX 01:51 · JFK 04:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.