最近我听到一些人说,在Linux中,使用进程几乎总是比使用线程更好,因为Linux在处理进程方面非常高效,而且与线程相关的问题太多了(比如锁)。然而,我对此持怀疑态度,因为在某些情况下,线程似乎可以带来相当大的性能提升。

因此,我的问题是,当遇到线程和进程都可以很好地处理的情况时,我应该使用进程还是线程?例如,如果我正在编写一个web服务器,我应该使用进程还是线程(或组合)?


当前回答

Linux(实际上还有Unix)为您提供了第三种选择。

选项1 -流程

创建一个独立的可执行文件来处理应用程序的某些部分(或所有部分),并为每个进程分别调用它,例如,程序运行自己的副本来委托任务。

选项2 -线程

创建一个独立的可执行文件,它由一个线程启动,并创建额外的线程来执行一些任务

选项3 -分叉

仅在Linux/Unix下可用,这有点不同。fork进程实际上是拥有自己地址空间的进程——子进程(通常)无法影响其父进程或兄弟进程的地址空间(不像线程)——因此您获得了额外的健壮性。

但是,内存页不是复制的,它们是写时复制的,因此通常使用的内存比您想象的要少。

考虑一个web服务器程序,它包含两个步骤:

读取配置和运行时数据 服务页面请求

如果您使用线程,第1步将完成一次,第2步将在多个线程中完成。如果您使用“传统”流程,那么每个流程都需要重复步骤1和步骤2,存储配置和运行时数据的内存也需要重复。如果您使用fork(),那么您可以执行第1步,然后fork(),将运行时数据和配置保留在内存中,不受影响,不复制。

所以实际上有三种选择。

其他回答

Linux(实际上还有Unix)为您提供了第三种选择。

选项1 -流程

创建一个独立的可执行文件来处理应用程序的某些部分(或所有部分),并为每个进程分别调用它,例如,程序运行自己的副本来委托任务。

选项2 -线程

创建一个独立的可执行文件,它由一个线程启动,并创建额外的线程来执行一些任务

选项3 -分叉

仅在Linux/Unix下可用,这有点不同。fork进程实际上是拥有自己地址空间的进程——子进程(通常)无法影响其父进程或兄弟进程的地址空间(不像线程)——因此您获得了额外的健壮性。

但是,内存页不是复制的,它们是写时复制的,因此通常使用的内存比您想象的要少。

考虑一个web服务器程序,它包含两个步骤:

读取配置和运行时数据 服务页面请求

如果您使用线程,第1步将完成一次,第2步将在多个线程中完成。如果您使用“传统”流程,那么每个流程都需要重复步骤1和步骤2,存储配置和运行时数据的内存也需要重复。如果您使用fork(),那么您可以执行第1步,然后fork(),将运行时数据和配置保留在内存中,不受影响,不复制。

所以实际上有三种选择。

我不得不同意你所听到的。当我们对我们的集群(xhpl等)进行基准测试时,我们总是通过进程而不是线程获得明显更好的性能。< /轶事>

其他人讨论了这些考虑因素。

也许重要的区别是,在Windows中,与线程相比,进程是沉重和昂贵的,而在Linux中,差异要小得多,所以等式在不同的点上平衡。

Threads -- > Threads shares a memory space,it is an abstraction of the CPU,it is lightweight. Processes --> Processes have their own memory space,it is an abstraction of a computer. To parallelise task you need to abstract a CPU. However the advantages of using a process over a thread is security,stability while a thread uses lesser memory than process and offers lesser latency. An example in terms of web would be chrome and firefox. In case of Chrome each tab is a new process hence memory usage of chrome is higher than firefox ,while the security and stability provided is better than firefox. The security here provided by chrome is better,since each tab is a new process different tab cannot snoop into the memory space of a given process.

更复杂的是,还有线程本地存储和Unix共享内存。

Thread-local storage allows each thread to have a separate instance of global objects. The only time I've used it was when constructing an emulation environment on linux/windows, for application code that ran in an RTOS. In the RTOS each task was a process with it's own address space, in the emulation environment, each task was a thread (with a shared address space). By using TLS for things like singletons, we were able to have a separate instance for each thread, just like under the 'real' RTOS environment.

共享内存(显然)可以为您带来让多个进程访问相同内存的性能优势,但代价是必须正确地同步进程。一种方法是让一个进程在共享内存中创建一个数据结构,然后通过传统的进程间通信(如命名管道)向该结构发送句柄。