Node.js确实有一个扩展,叫tagg,可以实现多线程。但实际上是这样的,它的这个多线程只是一个线程池,去执行一部分计算的任务。
EventLoop和IO的处理部分始终是单线程的,在任务线程中不能调用异步接口,只能计算或者执行阻塞IO。
除了tagg之外,Node.js还有child_process,cluster等扩展可以实现多进程。但这里的多进程也不知真正意义上的子进程。而是node的另外一个实例。它无法继承使用父进程的任何资源。
注:有好多同学说,单线程EventLoop足够用了。各位可以写个简单的程序测试看下,单线程EventLoop+EchoTCP和多线程程序在多核机器上有没有差距。
比如父进程中监听了一个端口,那么使用child_process创建了子进程后,实际上是没有这个server socket的。Node.js用了比较奇特的方式,通过sendmsg系统调用将这个socket的控制栈发过来了,子进程才能操作这个socket。
呵呵,问题又来了。相同的socket如果加入了不同的EventLoop中会发生惊群(epoll_wait all return)。一旦有请求进入(connect),那操作系统会唤醒所有子进程。只有1个进程最后会成功(accept),其他的进程都会失败(errno=EAGAIN),白白浪费了资源。
还有一个问题,如果进程1接受了连接A,这个进程就会持有此TCP连接,并加入EventLoop。进程2接受了连接B。那么A和B之间能通信么?只能说呵呵了。
A和B要通信,方法也有。1,再用sendmsg把这个socket也发给另外的进程,这个是不可行的,会严重加重惊群问题。2,使用管道通信,A将信息通过管道转发给进程2,进程2再send给连接B。这个方案是可行的。但需要用户自己去做,或者借助某个框架。
好了,这里就介绍完了。各位大致明白这个意思就行。我说的也不一定对哦,欢迎各位懂Node.js的同学来评论。