如何操作阻塞?感谢回复!
发布于 3年前 作者 leolovenodejs 1825 次浏览

实例代码:(请求处理程序模块)

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时不产生阻塞,谢谢~

22 回复

LZ不要这么色嘛 XD

为啥要睡10秒呢?

不要寫while(true)來阻塞就好了啊, 改用setTimeout或者tick來讓main thread有空閒取task

看一下 http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#event-loops

了解一下js的工作原理會有幫助

node是单线程的,你阻塞了10秒肯定什么都执行不了了,把sleep()删了不就行了… 或者用setTimeout

可以通过child_process 模块来解决这个问题

var exec = require("child_process").exec

然后通过exec(function(){…})来调用相应的功能函数,这样就可以实现非阻塞调用。

也就是说只要把功能函数放置在exec()里就好了?如果同时有很多请求并发,刚好有一个功能函数是执行很耗时的操作,那其它的请求不会因此阻塞对吗?谢谢~

仅仅是测试,我的本意是:有很多请求并发,而刚好其中有1个功能函数很耗时,在这种情况下其它请求如何避免阻塞。呵呵

仅仅是测试,我的本意是:有很多请求并发,而刚好其中有1个功能函数很耗时,在这种情况下其它请求如何避免阻塞。呵呵

仅仅是测试,我的本意是:有很多请求并发,而刚好其中有1个功能函数很耗时,在这种情况下其它请求如何避免阻塞。呵呵

还是不会用啊,能给我举个例子不:)

@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的优势

@luinlee 如果并发查询数据库的请求(如购票)很多,node也会开启很多线程吗?如是这样,那我还是不能很好理解它那个单线程的含义!

@normanzb2 假设我不用while(true)循环模拟阻塞,并假设testTimeout函数会耗时一些时间,如何处理来达到以下效果:请求sayHello时,OK,会很快,因为它不耗时,而请求testTimeout时会有耗时;即有阻塞的testTimeout请求处理对sayHello没有影响。谢谢~

@luinlee 假如放在一个整体上考虑:我们有很多web workers,情况会是怎样呢?谢谢~

@leolovenodejs node中的单线程是对开发者而言的,不存在createThread这样的函数来让开发者在node中创建线程,但是不代表node本身不能多线程允许。node内部通过libev实现了IO操作的异步,具体是多线程还是多进程实现的开发者可以不关心,只要知道进行这些操作时不会阻塞就好了。

我觉得这里面有个时间差、概率、和服务器性能等相关因素;那如果实际应用中只配1个服务器可以吗?

@luinlee 谢谢~ 不过我还是很晕啊!我在想想…

@leolovenodejs 一个服务器,多个进程,就不会阻塞了,http服务的进程,每个client连接上来的处理逻辑不阻塞,计算在另外一个进程中,处理完之后通知http服务进程,然后返回数据给client。这样子,http服务始终是通常的,其他的服务用户照常访问,只是访问处理速度慢的这个模块,用户会等待一会。

用settimeout 10s后再执行

node单线程 while(true)会堵塞住这个线程,自然就这样了

推荐你整个串行队列

@fish 恩 对,我就是要达到这个效果。谢谢~

回到顶部