我在paper中读到创建进程和线程的底层系统调用实际上是相同的,因此在线程上创建进程的成本并不是那么高。
修改
引用文章:
用进程替换pthreads的成本非常低廉, 尤其是在调用pthread和进程的Linux上 使用相同的底层系统调用。
答案 0 :(得分:19)
进程通常使用fork
创建,线程(轻量级进程)现在通常使用clone
创建。然而,有趣的是,存在1:N线程模型,它们也没有。
fork
和clone
都在内部映射到相同的内核函数do_fork
。此函数可以创建一个轻量级进程,该进程与旧的共享地址空间,或者单独的进程(以及许多其他选项),具体取决于您向其提供的标志。 clone
系统调用或多或少是该内核函数的直接转发(并由更高级别的线程库使用),而fork
将do_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
创建它们。我想内核正在共享一些代码来实现clone
,fork
等......(因为某些功能,例如virtual address space的管理是常见的)。
实际上,在大多数Unix系统上,进程创建(以及线程创建)通常都非常快(因为它们使用copy-on-write的virtual 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浏览器是一种多线程技术被认为比多线程更合适的经典示例。