Linux应用程序通常派生然后执行(使用execve()),但是Java应用程序和某些Apache MPM使用线程。如果进行分叉,请使用fork + exec生成进程,线程的高级版本是什么?JVM或Worker MPM如何产生线程?
Linux应用程序通常派生然后执行(使用execve()),但是Java应用程序和某些Apache MPM使用线程。如果进行分叉,请使用fork + exec生成进程,线程的高级版本是什么?JVM或Worker MPM如何产生线程?
Answers:
线程和进程背后的想法大致相同:您分叉执行路径。否则,线程和进程在诸如内存之类的事物上会有所不同。即,进程具有不同的VM空间,而线程共享拆分前存在的任何内容。
通过使用clone()调用(man 2 clone)在线程和派生工作的基础上:
与fork(2)不同,clone()允许子进程与调用进程共享其执行上下文的部分,例如内存空间,文件描述符表和信号处理程序表。(请注意,在此手册页上,“调用过程”通常对应于“父过程”。但是请参见下面的CLONE_PARENT的描述。)
clone()的主要用途是实现线程:程序中的多个控制线程在共享内存空间中同时运行。
区别来自传递给clone()的标志。从手册页可以看到,fork和threading只是clone()的一组预定义参数。但是,也可以用它来做定制的东西。
大多数非Unix多处理操作系统(OS)使用“ spawn()”调用或类似方法来生成新的OS进程或控制流。Spawn()往往是一个非常复杂的调用,具有很多选项和大量开销。Unix的一项创新是提供一种创建进程的开销要低得多的方法-fork()。Unix通过使用exec()在spawn()的另一半之前允许任意数量的处理,来照顾了spawn()的许多必要选项。
随着Unix及其变体的使用越来越多,发现低开销的进程创建是有用的,并且被使用。实际上,它的使用非常广泛,以至于人们希望使用更低的开销来创建进程,因此“线程”的思想应运而生。最初,线程是完全由原始进程处理的(JVM之类的程序可以通过“绿色线程”来完成);但是处理多线程调度很棘手,而且经常做错。因此,存在一种更简单的中间线程处理方式,其中OS处理调度,但通过(通常)在线程之间共享地址空间来节省一些开销。
您的问题很难回答,因为存在多个不同但相关的概念,它们都是“线程”,并且要详细说明,您需要一个形容词来描述您所引用的对象。另一方面,了解差异可能会导致您找到想要的特定答案。查找诸如“轻量级进程”,“用户线程”和“ rfork()”之类的详细信息。
CreateProcess()
没什么类似fork()
。
fork()
。
线程和派生实际上是两个不同的概念,它们都存在于Unix / Linux系统中(并且都可以在C / C ++中使用)。
fork()的想法(基本上是)是创建一个单独的进程,该进程具有与父进程相同的执行代码,并从fork行开始执行。将fork与exec函数一起使用的目的是exec函数会在结束时关闭调用它们的进程。因此,您通常会分叉,获取每个进程的PID(孩子的PID始终为0),并使父进程等待孩子完成执行exec函数。
线程用于并行处理(请记住,父级通常在派生程序中等待子级)。诸如C / C ++中的pthread(执行Google搜索)之类的线程将与主进程并行运行,并且可以与原始程序共享全局变量和全局函数。由于Java线程的行为类似,因此我可以想象它们的行为更像这些线程,而不像分支过程。
基本上,分支和线程之间是有区别的。他们做的事情截然不同(尽管看起来很相似)。这些概念可能很难理解,但是如果您有诚实的了解,可以通过(广泛的)研究来学习它们。
编辑#1
请参阅这些示例,了解如何调用和使用fork和线程。请注意exec函数的行为及其对主程序的影响。
http://www.jdembrun.com:4352/computerScience/forkVSthread.zip
pthread
API,不是线程实现。
JVM和Apache MPM都依赖内核获取本机线程。也就是说,他们使用操作系统进行调度。当然,两者都需要使用自己的API来跟踪内容。
Stackoverflow已经有几个问题要解决:
Apache有两种类型的MPM:Prefork(每个线程一个进程)和Worker(处理多个线程):Apache MPM。查看参考codebucket
如果进行分叉,请使用fork + exec生成进程,线程的高级版本是什么?JVM或Worker MPM如何产生线程?
那是特定于平台的,但是在Linux上,我假定许多其他POSIX兼容系统,它们使用pthreads(用户级线程API)的本地实现。例如:
#include <pthread.h>
pthread_t tid;
pthread_create(&tid, NULL, somefunc, NULL);
启动一个新线程,将somefunc
其作为第一个执行点。
您还可以创建线程-与分支不同,因为它们共享父进程相同的全局堆内存空间,而不是获得它的重复副本(但请注意,每个线程都使用自己的独立堆栈内存执行)-与clone()
系统调用一起使用,这是pthread在其之上构建的。