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

时间:2012-02-28 07:04:30

标签: linux multithreading process system-calls

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

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

修改
引用文章:

  

用进程替换pthreads的成本非常低廉,   尤其是在调用pthread和进程的Linux上   使用相同的底层系统调用。

3 个答案:

答案 0 :(得分:19)

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

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

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

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

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

答案 1 :(得分:3)

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

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

由于Linux上的大多数C standard library实施都是free software,因此您可以研究系统中的GNU glibc实施源代码(通常是musl-libc,但有时会{{3}}或其他内容)。

答案 2 :(得分:0)

如果你正在使用C,这里有一些可能对你有用的东西:

Fork - 用于创建流程:http://en.wikipedia.org/wiki/Fork_(operating_system

线程的Pthreads库:http://en.wikipedia.org/wiki/POSIX_Threads

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

Google Chrome浏览器是一种多线程技术被认为比多线程更合适的经典示例。