我目前正在学习来自java背景的C#。为了实践经验,我决定创建一个简单的SMTP邮件应用程序。我很快就了解到C#提供了对同步和异步套接字的支持。
在我看来,使用同步套接字与异步套接字相比并没有什么真正的优势,因为异步套接字不会阻塞,因此不需要每次都创建一个新线程。使用其中之一似乎也没有明显的开销。
所以我的问题是,在大多数情况下,使用同步套接字是否有优势,还是只使用异步套接字更好?
发布于 2014-11-12 02:12:22
任何一种机制都会起作用。主要区别在于,同步意味着要么阻塞本来会做其他有用事情的线程,要么为每个连接指定一个线程。无论哪种方式,这都不能很好地扩展。对于活动连接很少或只有一个活动连接的简单应用程序,这可能是可以的。
但是对于需要处理大量并发连接的任何场景,异步API是唯一能够提供足够性能的API。此外,在任何交互式场景中(例如,您必须处理用户输入和输出),异步方法更容易与用户界面集成。尤其是现在我们在C#中有了async和await。
发布于 2014-11-12 04:24:53
异步IO可保存线程。一个线程消耗(通常) 1MB的堆栈内存。当并发未完成IO操作的数量变大时,这是使用异步IO的主要原因。根据我的测量,在进入数千个线程之前,操作系统的可伸缩性并不是一个问题。
主要的缺点是需要更多的开发工作才能使相同的应用程序在相同的可靠性水平上工作。
I have written about this tradeoff at length.还包括:Should we switch to use async I/O by default?
建议始终使用异步IO客观上是错误的建议。
发布于 2019-10-11 14:59:43
独立于你正在使用的编程语言,只建议使用异步套接字是一个糟糕的建议。诚然,所有问题都可以使用异步解决,但并非所有问题(例如100'000个连接)都可以使用同步解决。但大多数时候,问题往往更简单(<100个连接)。
在我的经验中,(平庸的)程序员倾向于迷失在他们使用异步套接字创建的混乱中,而在单独的线程中处理同步套接字是简单的,可以理解的,也更容易维护。在Windows下创建线程是很昂贵的,假设有一个合适的操作系统,它的开销要小得多(在x86 /Linux上是5 us )。另外,线程不需要占用1MB的RAM (至少本机程序不需要),而堆栈和状态(寄存器)需要占用几kb的内存。
最重要的是,许多人认为同步套接字编程速度较慢,但事实并不总是如此。上下文切换(到其他线程)是有代价的,但是异步套接字接口对于操作系统内核来说也不便宜。
一如既往:选择最适合情况的解决方案。
https://stackoverflow.com/questions/26863321
复制相似问题