实例代码:(请求处理程序模块)
sayHello : function(response,request){
response.writeHead(200, {"Content-Type":"text/plain"});
console.log('你好!');
response.write("你好!");
response.end();
},
testTimeout : function(response,request){
function sleep(milliSeconds) {
var startTime = new Date().getTime();
while (new Date().getTime() < startTime + milliSeconds);
}
sleep(10000);
response.writeHead(200, {"Content-Type":"text/plain"});
console.log('testTimeout end...');
response.write("testTimeout end...");
response.end();
}
当有请求testTimeout时,系统会阻塞10秒,而此时如果同时请求sayHello,系统也会阻塞10秒,麻烦请问如何处理能让在请求sayHello时不产生阻塞,谢谢~
不要寫while(true)來阻塞就好了啊, 改用setTimeout或者tick來讓main thread有空閒取task
看一下 http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#event-loops
了解一下js的工作原理會有幫助
可以通过child_process 模块来解决这个问题
var exec = require("child_process").exec
然后通过exec(function(){…})来调用相应的功能函数,这样就可以实现非阻塞调用。
@leolovenodejs 分情况:对io/数据库(socket)操作使用异步函数,node会使用多线程实现,不用担心它耗时。CPU密集的操作可以编写单独的程序处理,在node中通过“child_process”或消息队列调用。
@leolovenodejs main thread 已經阻塞了,再fork進程也沒用吧,正常情況如果真有人做了一個阻塞的操作,並且已經開始運行了,你是沒法插入進去的,js中其實有task queue的概念,每個阻塞的片段都可以當做一個task,main thread一旦空閒下來,就會選一個task queue, pick一個task,然後執行這個task,task執行完成後,再重複之前步驟。
因此如果你有一個while(true)在執行的話,main thread已經阻塞,其他的task都在task queue中永遠不被執行。
正確的解決方法是將cpu consuming的task拆分成小的片段,或者放到單獨的進程、或者web worker中執行。
同一个进程中,如果 功能函数 的计算任务在这个进程中完成,那么这个计算任务就会阻塞的,因为node现在还是单线程的。
所以像这种计算复杂、耗时严重的处理逻辑,可以像上面童鞋说的,再开一个进程,保证服务用户的进程不阻塞(这样其他功能的用户请求可用),同时另一个进程处理完成之后,将结果返回。
这样才能发挥出node的优势
@normanzb2 假设我不用while(true)循环模拟阻塞,并假设testTimeout函数会耗时一些时间,如何处理来达到以下效果:请求sayHello时,OK,会很快,因为它不耗时,而请求testTimeout时会有耗时;即有阻塞的testTimeout请求处理对sayHello没有影响。谢谢~
@leolovenodejs node中的单线程是对开发者而言的,不存在createThread这样的函数来让开发者在node中创建线程,但是不代表node本身不能多线程允许。node内部通过libev实现了IO操作的异步,具体是多线程还是多进程实现的开发者可以不关心,只要知道进行这些操作时不会阻塞就好了。
@leolovenodejs 一个服务器,多个进程,就不会阻塞了,http服务的进程,每个client连接上来的处理逻辑不阻塞,计算在另外一个进程中,处理完之后通知http服务进程,然后返回数据给client。这样子,http服务始终是通常的,其他的服务用户照常访问,只是访问处理速度慢的这个模块,用户会等待一会。