2013-11-22 83 views
1

我完全和节点和线程之间的差异混淆。现在在httpd文档中,他们说他们创建了一个主进程,它创建了一个子进程,该进程又保持了固定数量的线程。与node.js混淆VS apache HTTPD

线程池的工作方式与Apache的预分配类似。在程序启动时创建线程块,然后平均分配工作负载。 当连接数比线程多时,新连接有 需要等待。但另一方面,您可以节省创建线程的成本。

现在我怀疑这是因为线程可以与共享内存运行,为什么不能创建任何数量的线程?

说到节点。节点完全是事件驱动的。基本上,服务器由一个线程处理一个接一个事件组成。一个新的请求进入是一种事件。服务器开始处理它,当有一个阻塞的IO操作时,它不会等到它完成,而是注册一个回调函数。然后服务器立即开始处理另一个事件(也许是另一个请求)。当IO操作完成时,这是另一种事件,并且服务器通过一有时间就执行回调来处理它(即继续处理请求)。

现在,如果节点不创建新的线程,那么它如何接受新的请求。

+1

为什么java标签? –

+0

http://howtonode.org/understanding-process-next-tick – Damodaran

回答

2

从博客Understanding the node.js event loop

Node.js的保持你的代码的单个线程...

这真的是一个单独的线程运行:你不能做任何并行执行代码;做一个“睡眠”,例如将阻塞服务器一秒:

的源代码

while(new Date().getTime() < now + 1000) { 
    // do nothing 
} 

因此,尽管该代码运行时,Node.js的不会从客户的任何其它请求的响应,因为它只有一个执行代码的线程。或者如果你有一些CPU密集的代码,比如说调整图像大小,那么它仍然会阻止所有其他的请求。

查看博客了解更多详情。它正在详细解释事件循环。

编辑

检查这一点,一个很好的参考 Multi-Process Node.js: Motivations, Challenges and Solutions

+0

让我们说两个请求来同时然后哪一个将在node.js –

+0

进行第一个。计算中不能同时存在“两件事”,这不是量子物理中存在这样的概念。 –

+0

要完成@ N.B的回答,Node将处理第一个请求,并在其上分配唯一的计算线程。但在第一次异步调用(例如数据库查找或HTTP请求)时,它将处理事件循环中的下一个事件,这很可能是您的第二个请求。 –

1

与JavaScript的问题是,它是出了名的单线程。因此线程不能存在只是存在(有一些复杂的解决方案,但最终这些解决方案往往非常复杂)。 Node.js使用非阻塞IO方法来规避这种限制,最终通过避免任何阻塞并让这些任务经常暂停一秒以让其他人也做一些工作来巧妙地利用单线程。类似于Windows 95-ME中的旧单核多任务仿真。

现在最大的问题是:如果这些处理线程中的任何一个处于暂停状态,那么整个服务器都将处于暂停状态。只要小规模工作,这不是问题,但对于大型服务器环境而言,这绝对是不可行的。此外,现代服务器拥有8个或更多的内核,保持闲置的7个是硬件的巨大浪费。

工作者配置中的HTTPD会产生自己的一个分支(原始可执行文件充当备份以防万一),然后根据配置的值生成线程。它理论上可以同时运行1000个线程,但是如果你的CPU只有8个内核,显然这些线程中不能超过8个可以被处理。所以其他992个线程需要等待,这可以 - 根据任务的不同 - 甚至会导致客户端超时,因为他们必须等待超过30秒。

有多少线程a是一个很好的值主要取决于你的线程做什么。如果他们从不阻止,但花100%的时间来真正解决问题,那么关于核心* 2对于httpd来说是一个很好的价值,因为上面的核心限制。如果你的线程阻塞了很多(磁盘访问,tcp通信),那么更高或更高的值可能会导致更好的吞吐量。最终找到的唯一方法是针对服务器启动测试数据并测量各种配置中的吞吐量。然而,现代Web服务器(httpd已有数百年历史)结合了这两种方法:一个非阻塞的单个接收器线程,它读取数据,然后将其分发到可用的线程。这具有如下优点:IO操作快如闪电(如果代码是本机代码,甚至比node.js快),但是仍然可以同时使用所有内核。 Java可以通过NIO(新IO)完成此操作,然后将Runnables分配给Executors