Linux系统调用创建进程和线程

问题描述 投票:11回答:3

我在paper中读到,创建进程和线程的底层系统调用实际上是相同的,因此在线程上创建进程的成本并不是那么高。

  • 首先,我想知道创建进程/线程的系统调用是什么(可能是示例代码或链接?)
  • 其次,作者是否正确地假设创建进程而不是线程是否便宜?

编辑: 引文:

用进程替换pthread是非常便宜的,特别是在使用相同底层系统调用调用pthread和进程的Linux上。

linux multithreading process system-calls
3个回答
19
投票

进程通常使用fork创建,线程(轻量级进程)通常使用clone创建。然而,有趣的是,存在1:N线程模型,它们也没有。

forkclone都在内部映射到相同的内核函数do_fork。此函数可以创建一个轻量级进程,该进程与旧的共享地址空间,或者单独的进程(以及许多其他选项),具体取决于您向其提供的标志。 clone系统调用或多或少是该内核函数的直接转发(并由更高级别的线程库使用),而forkdo_fork包装到具有50年历史的传统Unix函数的功能中。

重要的区别在于fork保证完整,单独的地址空间副本。正如巴兹尔所指出的那样,现在这种写作是通过写时复制完成的,因此并不像人们想象的那么昂贵。 创建线程时,它只是重用原始地址空间和相同的内存。

但是,不应该假设在类似unix的系统上创建进程通常是“轻量级”的,因为写时复制。它比Windows下的重量要轻一些,但它远没有那么自由。 一个原因是虽然没有复制实际页面,但新进程仍然需要页表的副本。对于使用大量内存的进程,这可能是几千字节到几兆字节的内存。另一个原因是虽然写时复制是不可见的并且是一种巧妙的优化,但它并不是免费的,它也不能做到魔法。当任何一个过程都不​​可避免地修改数据时,受影响的页面就会出错。

Redis就是一个很好的例子,你可以看到fork是除了轻量级之外的一切(它使用fork进行后台保存)。


3
投票

创建线程的底层系统调用是clone(2)(它特定于Linux)。顺便说一句,Linux系统调用列表在syscalls(2)上,你可以使用strace(1)命令来理解某些进程或命令完成的系统调用。过程通常使用fork(2)(或vfork(2)创建,这些日子并不是很有用)。但是,您可以(以及某些C标准库可能会这样做)使用某种特定形式的clone创建它们。我想内核正在共享一些代码来实现clonefork等......(因为一些功能,例如virtual address space的管理,很常见)。

实际上,在大多数Unix系统上,进程创建(以及线程创建)通常都非常快(因为它们使用copy-on-write机器用于virtual memory),通常只有一小部分毫秒。但你可能会有病态病例(例如thrashing),这会使病情长得多。

由于大多数C standard library实现都是Linux上的free software,你可以研究你系统上的GNU glibc的源代码(通常是musl-libc,但有时候是http://en.wikipedia.org/wiki/Fork_(operating_system或其他东西)。


0
投票

如果您使用C,这里有一些可能对您有帮助的东西:

Fork - 用于创建过程:http://en.wikipedia.org/wiki/POSIX_Threads

Pthreads Library for threads:qazxswpoi

如果您使用的是C ++,可以查看Boost Threads Library以进行线程化。

Google Chrome浏览器是一个经典的例子,其中多处理技术被认为比多线程更合适。

© www.soinside.com 2019 - 2024. All rights reserved.