据说Node(和可能的扭曲等)相对于更传统的线程服务器的主要好处之一是事件循环模型实现的非常高的并发性。最大的原因是每个线程都有很高的内存占用,并且交换上下文相对昂贵。当你有数千个线程时,服务器将大部分时间花在从线程到线程之间。
我的问题是,为什么操作系统或底层硬件不支持更轻量级的线程?如果他们这样做了,你能解决普通线程的10k问题吗?如果他们不能,那为什么?
答案 0 :(得分:3)
现代操作系统可以支持执行大量线程。
更一般地说,硬件越来越快(最近,它以越来越多的方式变得更快,多线程和多处理比单线程事件循环更友好 - 即核心数量增加,而不是增加处理吞吐量单核心的能力)。如果你今天负担不起线程的开销,你明天就可以负担得起。
Twisted的合作多任务系统(可能是Node.js等人)提供的先发制人多线程(至少以pthreads的形式)是易于编程的。
正确使用多线程涉及比正确使用单线程要小心得多。事件循环只是在不超出单个线程的情况下完成多项工作的手段。
考虑到并行硬件的激增,多线程或多处理的理想选择变得更容易(并且更容易正确)。演员,消息传递,甚至是petri网都是人们试图解决这个问题的一些解决方案。与主流多线程方法(pthreads)相比,它们仍然非常有限。另一种方法是SEDA,它使用多个线程来运行多个事件循环。这也没有流行起来。
所以,使用事件循环的人可能已经确定程序员的时间比CPU时间更有价值,并且使用pthreads的人可能已经决定了相反的情况,并且人们在探索演员等时会更喜欢这两种时间高度(显然是疯了,这可能就是为什么没有人听他们)。
答案 1 :(得分:0)
问题实际上并不是线程的重量级,而是编写正确的多线程代码需要锁定共享项并阻止它使用线程数进行扩展,因为线程最终会等待彼此获得锁定并且您很快就会达到添加其他线程无效的程度,甚至会在您获得更多锁争用时降低系统速度。
在许多情况下,你可以避免锁定,但很难做到正确,有时你只需要锁定。
因此,如果你只限于少量的线程,你可能会发现,除去必须锁定资源的开销,甚至考虑它,使得单线程程序比多线程程序更快,无论如何你添加了很多线程。
基本上锁可以(取决于你的程序)非常昂贵,并且可以阻止程序扩展超过几个线程。你几乎总是需要锁定某些东西。
线程的开销不是问题,而是线程之间的同步。即使您可以立即在线程之间切换,并且具有无限的内存,如果每个线程最终都在队列中等待轮到某个共享资源,那么这一点都无济于事。