×

Loading...

@Vancouver

Topic

  • 工作学习 / 学科技术 / 今天抽空大概看了看node.js,就这个单线程event的问题说说。 +2
    本文发表在 rolia.net 枫下论坛我没太仔细研究,所以只是粗谈,很多概念都是以前积累的,也许有记错的,还请大家海涵。

    Javascript和C++并不存在谁强谁弱的问题。说到底,语言是工具,能用不同的工具干不同的事情更重要。node.js整个底层是chromeV8引擎。V8就是用C++写的。所以说JavaScript可以用event调用,而C++只能调线程,这个看法并不正确。C++几乎可以干任何事情,只是大家有没有这样去用而已。

    javascript的单线程并行是误传,单线程永远是不能并行的。在V8引擎的后台其实是有线程池的。所谓的单线程只是指运行你的javascript代码的那个主线程。一旦你发出event了,里面是有其他线程来处理这些消息的。event解决的是一个阻塞的问题。

    说到阻塞,阻塞很多地方都有,最常见的就是网卡,硬盘,数据库。比如用C++写一个socket程序(web服务器最底层的一些代码)
    newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
    if (newsockfd < 0) error("ERROR on accept");
    pid = fork(); // 这里就开始起线程了。
    if (pid < 0) error("ERROR on fork");
    if (pid == 0) {
    close(sockfd);
    dostuff(newsockfd); //这里开始干活了,干什么呢?读写网卡。阻塞问题就出在这里。
    exit(0);
    } else close(newsockfd);

    n = write(sockfd,buffer,strlen(buffer)); n = read(sockfd,buffer,255); 这两个读写,都是阻塞的。于是一个人在那里读写,就都等着。等着网络慢慢把数据传过来,等着缓存,等着读。等死人。

    那么后来呢,就有了select/poll。 select/poll的好处就是你不用等了。有一个监听者来给你轮询。看看你这个socket读完了没有啊?没有?没有继续读,不等。读完了?读完了就处理。轮询呢?有几个人在连,就问几个人。那有些人根本就是闲着,你也去问?这也慢。所以后来就有了epoll。epoll就不是轮询了,e就是event。所以说C++没有event那个是不明所以。网卡数据读到了,发一个event出来,然后就处理。那线程呢?线程就解放了。以前是有一个请求你就起一个线程来处理,现在是一个线程可以处理好多个请求,因为在等网卡的那闲工夫它可以干其他事情么。所以就有了worker线程,也就有了线程池。通过有限的worker线程,来处理更多的请求。那么这个做得最好的一位就是nginx。所以谈到web服务器,大家就拿aparche来说事。其实Aparche做得是很烂的。真正要讲速度,应该谈nginx,这位实现了我上面讲的所有技术。当年看它的源码的时候,发现它什么都支持。当然是需要配置的。配置得不好也慢。

    当然,node.js还有很牛的地方就是一切皆事件,也就是把一切io都可以多线程干了。nginx作为web服务器,这是它的本职,但你写数据库那是应用的事情。它就不管了。而node。js因为它是javascript语言么,所以这个利用线程池就是随时随地都可以用。这方面的确不错。但是node.js主线程的程序复杂呢?那它就完了。因为它是一个单线程程序啊。你如果把主线程block住,node.js就死掉了。所以再好的工具也得会用才行。当然,node.js之所以快,不是因为javascript快,而是因为V8引擎快。说到底还是C++快。在此向google表达一下敬意。更多精彩文章及讨论,请光临枫下论坛 rolia.net
    • 高,这个要顶。
    • 如果node.js相当于apache / nginx,那么V8引擎相当于什么?
      • V8是Javascript的引擎,其实node.js里面还有其他模块。
    • 老兄,fork创建的是进程。C或C++的event driven编程十几年前就有。
      • 哈哈,真给你看出来了。网上copy了一段程序,随手就用了。
        • 更正如下
          if( pthread_create( &thread_id , NULL , connection_handler , (void*) &newSocket) < 0)
          {
          perror("could not create thread");
          return 1;
          }

          至于event driven在C++里面几十年前就有了,这个我只是基于有人说C++做不到event driven而言。哎,无所不能的C++啊,写得越多,错得越多的C++啊。:)88了。
          • 这样大流量的,业务复杂,可靠性要求高的互联网服务器,恐怕是多进程而不是多线程的。
            • 分布式?
            • 进程和线程之争一只存在着。所谓进程更安全,其实是有点无赖的。
              进程的好处就是一旦一个进程死了,整个服务器不受影响继续运行。这当然是更加安全的。但是问题是怎么就能死了呢?作为一个程序员,你写的程序上了线还能死掉,这是一种侮辱啊。

              线程当然没有进程可靠,但是线程的系统开销要小多了。当然,node.js表示,谁在乎这个?你爱用啥就用啥。

              You can start new processes via child_process.fork() these other processes will be scheduled in parallel. For load balancing incoming connections across multiple processes use the cluster module.
              接着又说:
              These child Nodes are still whole new instances of V8. Assume at least 30ms startup and 10mb memory for each new Node. That is, you cannot create many thousands of them.

              如果用进程,请想一想如果你的服务器有成千上万的用户接入,结果是什么?比死掉好不到那里去。
              • 不了解node.js,凭经验用不用cluster是搭建系统的事吧,跟写代码没关系。 +1
                • cluster 是搭建,但是用进程还是线程这是程序决定的。
                  • 要么就上面那位提的分布式,要么就是线程。
                    • 如果一套系统处理不了,就多套系统(cluster),这时一般连机器也是多台。 +1
                      • asynchronous ,thread-based 和 Parallel programming 是有区别的, nodejs 是 asynchronous programming +1
                        • Node.js还真提供一套进程间的通信机制,有意思。还不理解它的好处。
                          • 它的core能扫描event和管理他们
              • 没有bug的程序,你要么有勇气,要么无知,要么both.
                • 呵呵,有bug是可能会崩溃。一个服务器上开几千个进程是必定会崩溃,你选哪个?
              • oscargee,咱们开始练Erlang吧。那玩意可是进程orientated,号称C++的killer。
                • 没兴趣,工作机会不多。
            • For APache server, it multi-process plus multip thread mode.
    • 明白人!霸王举鼎"(﹁""﹁)"
    • 技术不错,不过看的方向不对,要向上看,不要向下看。 +1
      • 高论,不妨多讲讲?
    • 精神值得嘉许 可惜似乎很多基本概念都没弄清楚 把请求处理模式 编程语言 编译器 操作系统层都混淆起来 变成一团浆糊 可以把菜鸟外行人糊弄得一愣一愣的 但碰到懂多一点点的就碰壁了
      • 说得好,有时间不妨来多谈谈。
    • what's the difference between process and thread?