Linux系统调用创建进程和线程
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux系统调用创建进程和线程相关的知识,希望对你有一定的参考价值。
我在paper中读到,创建进程和线程的底层系统调用实际上是相同的,因此在线程上创建进程的成本并不是那么高。
- 首先,我想知道创建进程/线程的系统调用是什么(可能是示例代码或链接?)
- 其次,作者是否正确地假设创建进程而不是线程是否便宜?
编辑: 引文:
用进程替换pthread是非常便宜的,特别是在使用相同底层系统调用调用pthread和进程的Linux上。
进程通常使用fork
创建,线程(轻量级进程)通常使用clone
创建。然而,有趣的是,存在1:N线程模型,它们也没有。
fork
和clone
都在内部映射到相同的内核函数do_fork
。此函数可以创建一个轻量级进程,该进程与旧的共享地址空间,或者单独的进程(以及许多其他选项),具体取决于您向其提供的标志。 clone
系统调用或多或少是该内核函数的直接转发(并由更高级别的线程库使用),而fork
将do_fork
包装到具有50年历史的传统Unix函数的功能中。
重要的区别在于fork
保证完整,单独的地址空间副本。正如巴兹尔所指出的那样,现在这种写作是通过写时复制完成的,因此并不像人们想象的那么昂贵。
创建线程时,它只是重用原始地址空间和相同的内存。
但是,不应该假设在类似unix的系统上创建进程通常是“轻量级”的,因为写时复制。它比Windows下的重量要轻一些,但它远没有那么自由。 一个原因是虽然没有复制实际页面,但新进程仍然需要页表的副本。对于使用大量内存的进程,这可能是几千字节到几兆字节的内存。另一个原因是虽然写时复制是不可见的并且是一种巧妙的优化,但它并不是免费的,它也不能做到魔法。当任何一个过程都不可避免地修改数据时,受影响的页面就会出错。
Redis就是一个很好的例子,你可以看到fork
是除了轻量级之外的一切(它使用fork
进行后台保存)。
创建线程的底层系统调用是clone(2)(它特定于Linux)。顺便说一句,Linux系统调用列表在syscalls(2)上,你可以使用strace(1)命令来理解某些进程或命令完成的系统调用。过程通常使用fork(2)(或vfork(2)创建,这些日子并不是很有用)。但是,您可以(以及某些C标准库可能会这样做)使用某种特定形式的clone
创建它们。我想内核正在共享一些代码来实现clone
,fork
等......(因为一些功能,例如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或其他东西)。
如果您使用C,这里有一些可能对您有帮助的东西:
Fork - 用于创建过程:http://en.wikipedia.org/wiki/POSIX_Threads)
Pthreads Library for threads:qazxswpoi
如果您使用的是C ++,可以查看Boost Threads Library以进行线程化。
Google Chrome浏览器是一个经典的例子,其中多处理技术被认为比多线程更合适。
以上是关于Linux系统调用创建进程和线程的主要内容,如果未能解决你的问题,请参考以下文章