在线程创建和子进程创建中系统调用的区别是什么

时间:2012-06-28 11:00:14

标签: c multithreading unix process

如何在系统中完成线程的实现? 我知道使用fork()调用创建了子进程 并且线程重量轻。线程的创建与子进程的创建有何不同?

4 个答案:

答案 0 :(得分:2)

使用clone()系统调用创建线程,该调用可以创建一个与其父级共享内存空间和一些内核控制结构的新进程。这些过程称为LWP(轻量级进程),也称为内核级线程。

fork()创建一个新进程,最初与其父进程共享内存,但页面是写时复制的,这意味着当原始内容的页面内容时会创建单独的内存页面被改变了。因此,父进程和子进程都不能再改变彼此的内存,并且有效地将它们作为单独的进程运行。另外,新分叉的子进程是一个完整的进程,具有独立的内核控制结构。

答案 1 :(得分:1)

每个进程都有自己的地址空间 也就是进程可以访问的虚拟地址范围。当新进程 forked 时,必须复制所有涉及的资源。分叉完成后,孩子和父母有自己独特的地址空间和所涉及的所有资源。自然,这是一个性能密集型操作。

虽然 同一进程中的所有线程共享相同的地址空间 ,所以当一个新线程生成时,每个线程只需要自己的堆栈并没有像进程那样重复所有资源。线程产生线程的性能要低得多。

当然,这两个操作不能也不应该被比较,因为两者都为不同的要求提供了截然不同的特征。

答案 2 :(得分:0)

它非常不同,首先,子进程在某种程度上是父程序的副本,并且所有变量都是重复的,并且您的子进程与父进程的不同之处在于它的PID。线程就像新程序一样,它们与主程序同时运行(它看起来像是同时由于cpu切片的时间)。线程可以在程序中使用全局变量,但它们不会作为进程重复。因此,使用线程然后新进程要便宜得多。

答案 3 :(得分:0)

嗯,你已经阅读了重要的部分,现在这里是窗帘背后的东西:

在当前的实现中(当前意味着最近几十年),过程存储器在分叉时不会立即复制。只读部分只是在两个进程之间共享(因为它们无论如何都不能改变),当然还有共享库的只读部分。但最重要的是,所有可写的内容最初也只是共享。但是,它以写保护的方式共享,并且只要您写入子进程内存(例如通过递增变量),就会在内核中生成页面错误,这只会导致内核实际上复制相应的页面(然后进行修改)。

这种称为“写入时复制”的优秀优化导致子进程通常并不真正消耗与父进程完全相同的(物理)内存。然而,对于程序开发人员(和用户)来说,它是完全透明的。