在设计服务器时,我们正在考虑两种方法:
一种异步(基于选择)方法,因此后端 rpc 可以在单个线程中并行化。
一种同步方法,其中每个后端 rpc 在线程池中的另一个线程中处理。
需要权衡取舍:1 具有更好的性能,2 具有更少的代码复杂度。1 现在对于多核和 64 位的机器真的很重要吗?
在设计服务器时,我们正在考虑两种方法:
一种异步(基于选择)方法,因此后端 rpc 可以在单个线程中并行化。
一种同步方法,其中每个后端 rpc 在线程池中的另一个线程中处理。
需要权衡取舍:1 具有更好的性能,2 具有更少的代码复杂度。1 现在对于多核和 64 位的机器真的很重要吗?
我认为应该相反,async select() 方法使代码更简单,因为不涉及线程同步。
您需要做的就是将套接字句柄列表传递给 select() 函数。它将阻塞并且仅在一个或多个套接字句柄中发生某些事情时才返回。与使用线程池相反,您必须有一个作业调度队列,线程池中的所有线程都从中获取作业。
async select() 方法的缺点是它不会随着处理器内核的数量而扩展,因为所有内容都在一个线程中执行。
如果不了解有关服务器要求的更多详细信息,很难判断哪种方法可以为您提供更好的性能和/或降低代码复杂性。
有趣的是,在现实生活中的服务器设计中,性能和简单性通常是相辅相成的(但想出简单化的设计很难)。select/poll 本身不会自动为您提供更好的性能。而且线程池绝对不会降低你的代码复杂度。
回答你的问题:1仍然很重要。异步设计不能很好地扩展多进程机器,但只有当您的服务器在一个进程上运行时才会如此。如果您的服务器设计为在多进程机器上生成多个进程怎么办?不同的进程可以在不同的用户帐户下运行,并具有不同的安全设置。虚拟机呢?每个进程一个线程并不意味着您不能利用多核机器。
但是,我真的不记得上次看到基于 async select() 的真实服务器设计是什么时候了。也许在我上大学时的教科书中,但没有任何真正的生产系统。
这是一篇相关读物(它是一种少数派报告):
http://www.usenix.org/events/hotos03/tech/full_papers/vonbehren/vonbehren.pdf
这也是一个很好的资源:
http://www.kegel.com/c10k.html
请记住,您可以在某种程度上结合这两种方法,以最大限度地利用多核架构。假设您的服务器(“Krumpets here!”;)是可分区的——这意味着您可以在同一台机器上运行它的多个实例——使用 select 编写服务器,然后每个 cpu 核心运行一个服务器实例。